JDK8 知识点日常积累
目录
1. Consumer函数式接口的用法,通过consumer,可以进行函数式接口写法
2.* @FunctionalInterface 函数式接口的使用
3. 函数式接口的使用实例,JDK中的Predicate接口
一:小方法积累
【小知识点积累】
1. Stream.Of(T... value),该接口将直接返回value值的流对象,可以利用进行处理,ex:Stream.Of("A","A","A","A","A","A","A").forEach();
2. List集合的removeIf(),ex: list == "A","A","A","A","A","A"; list.removeIf(s -> s.equse("B")); 通过该表达式,可以将list中等于B的字符删除掉。
二:重点知识点积累
【中高知识点积累】
1. Consumer函数式接口的用法,通过consumer,可以进行函数式接口写法
ex:
/**
* @author hengtao.wu
* Consumer 为函数式接口体现,通过该接口,可以完成将特定值进行处理的实现。
* 该接口中核心接口有两个,
* ① accept,接受并处理传参
* ② andThen,执行完accept之后继续进行的操作
* @Date 2019/10/28 10:05
**/
public class ConsumerTest {
public static void main(String[] args) {
//lambda之前的写法,通过foreach的方式,将consumer创建实例并执行方法的方式作为参数,进行处理list中的元素
/*List<String> list = Arrays.asList("a","b","c","d","e");
List<String> result = new ArrayList<>();
list.forEach(new java.util.function.Consumer<String>() {
@Override
public void accept(String s) {
if(s.equals("a") || s.equals("c")) {
result.add(s);
}
}
});
System.out.println(result);*/
//other写法
List<String> result = new ArrayList<>();
Consumer<String> consumer = s -> {
if(s.equals("a") || s.equals("c")) {
result.add(s);
}
};
//执行accept之后继续处理的方法.
consumer.andThen(s -> {
result.removeIf(ss -> ss.equals("a"));
});
Stream.of("a",
"b",
"c",
"d",
"e").forEach(consumer);
System.out.println(result.toString());
}
//对比lambda表达式,consumer就显得比较冗余了。lambda表达式,会更简单
Stream.of("a",
"b",
"c",
"d",
"e").forEach(s -> {
if(s.equals("c")) {
result.add(s);
}
});
}
2.* @FunctionalInterface 函数式接口的使用
说明:该注解的意思是,将该接口生命为函数式接口,可以通过将匿名类/lambda表达式作为参数,进行方法传递,并且,该接口中必须只有一个实现方法。也就是说,任何使用匿名类/lambda进行参数传递时,都是默认实现了该方法进行实例化的。
例如:
@FunctionalInterface
public interface WorkService<T> {
void doSomeThing(T t);
}
****************************************
public class FunctionalInterfaceTest {
public static void test(WorkService workService) {
workService.doSomeThing("aaa");
}
public static void main(String[] args) {
//此时调用test方法时,将lambda表达式传入,默认就是实现了接口中的dosomething方法。
test((s) -> {System.out.println(s + "wahaha");});
//此时,实例化WorkService对象是,直接实现该接口中的doSomeThing方法,就完成了实例化。
WorkService<String> w = s -> {if(s.equals("a")) {
System.out.println("OK");
}};
w.doSomeThing("bb");
}
}
3. 函数式接口的使用实例,JDK中的Predicate接口
public class PredicateTest {
public static void main(String[] args) {
List<Integer> num = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
checkNum(num, new Predicate<Integer>() {
@Override
public boolean test(Integer integer) {
return integer%2 == 0;
}
});
//通过匿名内部类与通过lambda表达式所达到的效果是一致的,都是将函数作为参数,进行方法传递,从而达到实例化接口的作用。
checkNum(num, n -> n%2 == 0);
}
public static void checkNum(List<Integer> list, Predicate<Integer> predicate) {
list.forEach(integer -> {
// 此时的test方法,就是参数传递时,所表达的方法。
if(predicate.test(integer)) {
System.out.println(integer);
}
});
}
}
4. 四种常用函数式接口使用总结
/**
*四种常用接口简单举例总结
*/
public static void main(String[] args) {
//1. consumer接口,有参,无返回类型
List<String> list = Arrays.asList("a","a","a","a","a","a","a");
consumerTest(list, s -> {if("a".equals(s)) {System.out.println("执行删除操作!");}});
//2. 常用接口Supplier,无参 有返回值的函数式接口
Supptest(() -> {
String s = "aa";
return s + "bb";
});
//3. 常用接口Function,有参 有返回值的函数式接口
funcTest(100, num -> String.valueOf(num + 150));
//4. predicate接口,有参,有返回类型,参数为泛型,返回类型为固定Boolean型,主要用作验证、过滤等操作。
List<String> result = predicateTest(list, s -> "b".equals(s));
}
/**
*1. Consumer, 有参,无返回类型,主要进行一些判断后操作。参数类型为泛型
*/
public static void consumerTest(List<String> list, Consumer<String> consumer) {
list.forEach(consumer);
}
/**
* 2. 常用接口Supplier,无参 有返回值的函数式接口,返回类型为泛型
*/
public static String Supptest(Supplier<String> supp) {
return supp.get();
}
/**
*3. 常用接口Function,有参 有返回值的函数式接口,泛型定义参数类型与返回类型
*/
public static String funcTest(Integer num, Function<Integer, String> function) {
return function.apply(num);
}
/**
*4. predicate接口,有参,有返回值,返回值为固定Boolean类型,参数为泛型。主要用作验证、过滤等操作。
*/
public static List<String> predicateTest(List<String> list, Predicate<String> predicate) {
List<String> result = new ArrayList<>();
list.forEach(s -> {
if(predicate.test(s)) {
result.add(s);
}
});
return result;
}
5. 方法引用
public static void main(String[] args) {
/**
* 方法引用:
* 说明:用引用方法的方式,代替lambda表达式。
* 核心:① 被引用的方法参数、返回类型必须与函数式接口的抽象方法一致;
* ② 调用时,直接调用接口实例对象调用抽象方法即可直接调用被引用的方法
* 总结:其实就是通过引用实例方法的方式,实例化函数式接口,并实现该接口中的抽象方法。
* 换言之就是用引用别的方法的方式,替代了lambda表达式的写法
* 拓展:还有数组引用、构造器引用等方式。
*/
Boolean result = null;
//old way
MethodInterface<String, String, Boolean> methodInterfaceOld = (s1, s2) -> {
if(s1.equals(s2)) {
return true;
}else {
return false;
}
};
result = methodInterfaceOld.equalss("a","b");
//方法引用---1. 静态方法引用 类名::静态方法
// new way 其中equals()中的方法其实也是if else判断
MethodInterface<String, String, Boolean> methodInterfaceNew1 = StaticMethod::equals;
result = methodInterfaceNew1.equalss("a","b");
// old way === new way 一样的意思
//方法引用---2. 实例对象方法引用 对象::方法
Person person = new Person();
MethodInterface<String, String, Boolean> methodInterfaceNew2 = person::equals;
result = methodInterfaceNew2.equalss("s1","s2");
}
6. lambda与stream组合操作集合方法合辑
public static void main(String[] args) {
List<Person> javaProgrammers = getList2();
List<Person> phpProgrammers = getList1();
//1. 通过forEach改变集合中每个对象中的薪资值
javaProgrammers.forEach(j -> j.setSalary(j.getSalary() + 100));
//2. filter过滤器,过滤薪资超过1400$的。 filter中的参数值为pridicate函数式接口,可以为pridicate实例,或者直接是lambda表达式
phpProgrammers.stream().filter(p -> p.getSalary() > 1400)
.forEach(System.out::println);
//2.1 多过滤器,同时将年龄>25 ,薪资>1400的人员筛选出来并打印
Predicate<Person> ageFilter = p -> p.getAge() > 25;
Predicate<Person> salaryFilter = p -> p.getSalary() > 1400;
javaProgrammers.stream().filter(ageFilter)
.filter(salaryFilter)
.forEach(System.out::println);
//3. limit限制结果个数用法
javaProgrammers.stream().filter(ageFilter).limit(3).forEach(System.out::println);
//4. 排序,按照薪资大小排序
javaProgrammers.stream().sorted((j1, j2) -> j1.getSalary() - j2.getSalary()).forEach(System.out::println);
//5. min、max的用法,按照薪资排序,获取最大/最小的值
javaProgrammers.stream().min((j1, j2) -> j1.getSalary() - j2.getSalary()).get();
//6. 利用map()方法进行操作
//6.1 将name拼接返回字符串
String result = javaProgrammers.stream().map(j -> j.getFirstName()).collect(Collectors.joining(";"));
//6.2 将name获取,存在集合中
List<String> list = javaProgrammers.stream().map(j->j.getFirstName()).collect(Collectors.toList());
//6.3 并行map .sum 方法可被替换成其他,count/min/max/average/limit等...
int sum = javaProgrammers.stream().mapToInt(j->j.getSalary()).sum();
//6.4 还可以直接过去到IntSummaryStatistics对象,分别获取sum/min/max等汇总数据
IntSummaryStatistics intSummaryStatistics = javaProgrammers.stream().mapToInt(j->j.getSalary()).summaryStatistics();
intSummaryStatistics.getSum();
}