()->{}
():入参,可以是(i),(a,b)等等
{}:函数体。
函数式编程接口都只有一个抽象方法,因此编译器会先将这段函数编译,并将其当做抽象方法的实现,所以“=”后面的函数体可以看成是accept函数的实现。
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
accept方法
public class Function {
public static void main(String[] args) {
/*传统写法*/
Consumer<Integer> con = new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
System.out.println(integer);
}
};
con.accept(0);
/*函数式编程 写法一*/
Consumer<Integer> con_1 = (i) -> {System.out.println(i);};
con_1.accept(1);
/*函数式编程 写法二*/
Consumer<Integer> con_2 = (i) -> System.out.println(i);
//如果只有一个语句,可以省略{}
con_2.accept(2);
/*函数式编程 写法三*/
Consumer<Integer> con_3 = System.out::println;
//针对入参,调用pringln方法打印
con_3.accept(3);
}
}
andThen方法
指定当前consumer调用之后再让其他comsumer调用
/*定义第一个Consumer*/
Consumer<Integer> consumer1 = (param) -> System.out.println(param);
/*定义第二个Consumer*/
Consumer<Integer> consumer2 = (param) -> System.out.println(param * param);
/*consumer1可以连续的调用自己, 打印出 3 3 3*/
consumer1.andThen(consumer1).andThen(consumer1).accept(3);
/*consumer1可以调用自己后调用consumer2,打印出3 3 9*/
consumer1.andThen(consumer1).andThen(consumer2).accept(3);
注意:当一个Consumer接口调用另外一个Consumer对象时两个Counsumer对象的泛型必须一致。
接收一个参数并生成结果,所以该函数是有入参和返回的。
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
apply 方法
Function<Integer, Integer> function = new Function<Integer, Integer>() {
@Override
public Integer apply(Integer integer) {
return null;
}
};
Function<Integer, Integer> function_1 = i -> i+1;
System.out.println( function_1.apply(2) ); //输出3
Function编程接口有两个泛型Function<T, R>:T表示:函数的输入类型,R表示:函数的输出类型。
compose方法
Function<Integer, Integer> fun = res -> res + 1;
Function<Integer, Integer> fun1 = res -> res * 10;
Integer composeValue = fun.compose(fun1).apply(2);
System.out.println(composeValue); //输出21
fun在收到2之后,先将2交给fun1处理,之后再自己处理。
andThen方法(同上consumer)
Function<Integer, Integer> fun = res -> res + 1;
Function<Integer, Integer> fun1 = res -> res * 10;
Integer andThenValue = fun.andThen(fun1).apply(3);
System.out.println(andThenValue); //输出40
identity方法
将入参直接输出
System.out.println(Function.identity().apply("总分"));//输出:总分
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
test方法
自定义函数体,用于判断
Predicate<String> pre = res -> res.equals("1234");
boolean rest = pre.test("1234");
System.out.println(rest); //输出true
add方法
一个个执行
Predicate<String> pre = res -> res.equals("1234");
Predicate<String> pre1 = res -> res.equals("1234");
boolean rest = pre.and(pre1).test("1234");
System.out.println(rest); //打印:true
boolean rest1 = pre.and(pre1).test("12341");
System.out.println(rest1); //打印:false
negate方法
结果反转
default Predicate<T> negate() {
return (t) -> !test(t);
}
Predicate<String> pre = res -> res.equals("1234");
boolean rest = pre.negate().test("1234");
System.out.println(rest); //打印:false
or方法
只要有一个为true则为true
Predicate<String> pre = res -> res.equals("1234");
Predicate<String> pre1 = res -> res.equals("12341");
boolean rest = pre.or(pre1).test("12341");
System.out.println(rest); //打印:true
isEqual方法
判断是否相等
System.out.println(Predicate.isEqual("12345").test("12345"));//打印:true
通过Stream以及Optional两个类,可以进一步利用函数式接口来简化代码。
Stream可以对多个元素进行一系列的操作,也可以支持对某些操作进行并发处理。
方式一:list.stream()
List<String> list = Arrays.asList("a", "b", "c", "d");
Stream listStream = list.stream(); //获取串行的Stream对象
Stream parallelListStream = list.parallelStream(); //获取并行的Stream对象
方式二:Stream.of
Stream s1 = Stream.of("a", "b", "c", "d");
List<String> list = Arrays.asList("test", "t1", "t2", "teeeee", "aaaa");
filter
过滤stream中的元素,并将过滤的结果返回。
Stream<T> filter(Predicate<? super T> predicate);
示例:过滤包含“te”的元素
list = list.stream()
.filter(n -> n.contains("te"))
.collect(Collectors.toList()); //list:[test, teeeee]
map
元素一对一转换
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
示例:每个元素后面拼接“.txt”
list = list.stream()
.map(n -> n.concat(".txt"))
.collect(Collectors.toList());
//list:[test.txt, t1.txt, t2.txt, teeeee.txt, aaaa.txt]
flatMap
元素一对多转换
示例:各个元素拆分成单个字母
list = list.stream()
.flatMap(n -> Stream.of(n.split("")))
.collect(Collectors.toList());
//list:[t, e, s, t, t, 1, t, 2, t, e, e, e, e, e, a, a, a, a]
distinct
去重
list = list.stream()
.flatMap(s -> Stream.of(s.split("")))
.distinct()
.collect(Collectors.toList()); // list:[t, e, s, 1, 2, a]
Sorted
排序
list = list.stream()
.flatMap(s -> Stream.of(s.split(""))).
distinct()
.sorted().
collect(Collectors.toList()); // list:[1, 2, a, e, s, t]
用于简化java中对空值的判断处理,以防止空指针异常。
private final T value;
方式一
Optional o = Optional.of("test");
方式二
Optional.ofNullable()//构建一个optional对象,入参可以是空值
ifPresent
判断结果不为空
/*传统做法*/
String s = test();
if (null != s) System.out.println(s);
/*Optional做法*/
Optional<String> s = Optional.ofNullable(test());
s.ifPresent(System.out::println);
orElse
变量为空时,提供默认值
/*传统做法*/
if (null == s) s = "test";
System.out.println(s);
/*Optional做法*/
Optional<String> o = Optional.ofNullable(s);
System.out.println(o.orElse("test"));
orElseThrow
变量为空,抛异常
/*传统做法*/
if (null == s) throw new Exception("test");
System.out.println(s);
/*Optional做法*/
Optional<String> o = Optional.ofNullable(s);
System.out.println(o.orElseThrow(()->new Exception("test")));
List<User> list = Arrays.asList(new User("qq", 11), new User("ww", 22));
取集合各元素的某个属性为新的集合 -- map
List<String> nameList = list.stream()
.map(User::getName)
.collect(Collectors.toList());
// nameList :[qq, ww]
取集合各元素的某个属性,并经过一定操作,生成新的集合 -- map
List<Integer> ageList = list.stream()
.map(user -> user.getAge() + 1)
.collect(Collectors.toList());
//ageList : [12, 23]
取集合元素的某个属性的某个特征
List<Integer> nameLengthList = list.stream().
map(User::getName).
map(String::length)
.collect(Collectors.toList());
//nameLengthList : [2, 2]
转换成一个新对象的集合,并输出新对象
List<Person> personList = list.stream()
.map(user -> {
Person person = new Person(user.getName(), user.getAge());
return person;
})
.collect(Collectors.toList());
personList.stream()
.forEach(person -> System.out.println(person.name+" "+person.age));
针对各元素某个属性计算
/*写法一*/
int ageTotal = 0;
ageTotal = list.stream()
.map(User::getAge)
.reduce(ageTotal , (a,b)-> a+b);
//ageTotal = 33
/*写法二*/
Optional<Integer> ageTotal = list.stream()
.map(User::getAge)
.reduce((a, b) -> a + b);
//ageTotal .get() = 33
求某个元素某属性的最大值
Optional<Integer> max = list.stream()
.map(User::getAge)
.reduce(Integer::max);
//max = 22
java8中新增了三个原始类型流(IntStream、DoubleStream、LongStream)
sum()/max()/average()/count()
求和
int sum = list.stream().mapToInt(User::getAge).sum();// sum = 33
生产1-100之间的数字
IntStream intStream = IntStream.rangeClosed(1, 100);
1-100之间偶数个数
long count = IntStream.rangeClosed(1,100).filter(i->i%2==0).count();
//count = 50
Stream.of
Stream<String> str = Stream.of("i","love","this","game");
str.map(String::toUpperCase).forEach(System.out::println);
Arrays.stream
int[] num = {2,5,9,8,6};
IntStream intStream = Arrays.stream(num);
int sum = intStream.sum(); //求和
函数生成 -- 0开始后面10各数求和
Optional<Integer> optional = Stream.iterate(0, i -> i+1)
.limit(10)
.reduce((a, b)->a+b);
// optional.get() = 45
原文:https://www.cnblogs.com/xujiangjiang/p/12050191.html