JDK8中的接口
1.接口中可以定义静态方法
工具类:一个类中的所有方法都是静态方法(System/Math/Arrays等)
Collection工具类 | 用于各种集合的操作 |
Sort(List list) | 对list排序 |
reverse(List list) | 将list中元素倒序排列 |
shuffle(List list) | 将List中的元素随机排序 |
interface IA{
public static IA createIA(){
return new IA(){};
}
}
省去工具类!!
2.接口中可以定义默认的方法(保证接口的向后兼容性)
interface IA{
default void m1(){}
}
实现接口IA时, 就无须实现m1方法
菱形继承问题
(1)
class A{
public void m1(){}
}
interface B{
default void m1(){}
}
class C extends A implements B{
}
C中的m1方法来自 A类 类优于接口
(2)
interface A{
default void m1(){}
}
interface B{
default void m1(){}
}
class C implements A,B{
public void m1(){
A.super.m1(); // 调用A接口中的m1方法
B.super.m1(); // 调用B接口中的m1方法
}
}
C类必须覆盖m1方法, 否则编译出错
方法引用规则:
①父类优先于接口;
②子接口优于父接口;
③平级接口出现方法冲突,实现类必须主动覆盖;
④出现方法签名冲突,无法解决!!!
3.接口中可以定义私有默认方法(JDK9)
interface ID{
default void m1(){
print();
System.out.println("我是m1 谁敢删我");
}
default void m2(){
print();
System.out.println("我是m2 谁敢删我");
}
private void print(){
for(int i = 1 ; i <= 100 ; i++){
System.out.println("HelloWorld");
}
}
}
集合的排序 Comparator
abstract int compare(T o1, T o2) | 需要用户实现本方法,如果o1小于o2返回负数;如果o1==o2 返回0;如果o1大于o2 返回正数 |
reversed() | 返回反序排列的比较器 |
comparing(Function) | 利用Function返回的字段,进行自然排序 |
theComparing(Function) | 利用Function返回的字段,进行再次自然排序(用作第二条件) |
函数式编程
1.可重用性的实现:将代码的可变部分和不可变部分进行分离
- 添加函数的参数,将不变的数据作为函数的实现,将可变的数据作为函数的参数(数据参数化)
- 利用继承,将不变的代码放入父类,将可变的代码放到子类
- 利用泛型,将参数类型及返回值类型 作为变量
- 利用接口的回调,将代码装在接口对象中,作为参数(行为参数化,将代码作为参数)
2.Lambda表达式
函数式接口:只有一个抽象方法的接口
Lambda表达式:是匿名内部类的新颖的写法
(初级难度-->中级难度--->终极难度)
List<Student> result = findStudents(students,
new Predicate(){
public boolean test(Student s){
return s.getName().startsWith("W");
}
}
);
List<Student> result = findStudents(students,
(Student s)->{return s.getName().startsWith("W");}
);
List<Student> result = findStudents(students, s->s.getAge()>30);
接口名 | 方法描述符 | 方法名 |
Predicate<T> | (T)-->boolean | test |
Function<T,R> | (T)-->R | apply |
Consumer<T> | (T)-->void | accpt |
Supplier<T> | ()-->T | get |
3.方法引用
类型 | Lambda | 方法引用 |
参数方法 | (A a,B b)->a.method(b) | A::method |
静态方法 | (args) -> ClassName.method(args) | ClassName::method |
其他对象的方法 | (s) -> System.out.println(s) | System.out::println |
4.构造方法
类名::new 具体引用的是哪个构造方法,要根据上下文判定
Supplier<Worker> f = ()->new Worker();
Supplier<Worker> f = Worker::new;
Function<String,Worker> f = s->new Worker(s);
Function<String,Worker> f = Worker::new;
IntFunction<Worker> f = a->new Worker(a);
IntFunction<Worker> f = Worker::new;
BiFunction<String,Integer,Worker> f = (s,a)->new Worker(s,a);
BiFunction<String,Integer,Worker> f = Worker::new;
函数式数据处理
1.流的概念
集合:用来存储数据的容器
流(Stream):用来处理数据的工具
优势:
1.简化编程
2.提高数据的处理效率
2.流的运算过程
中间操作:Stream<T>
方法 | 作用 | 返回值 |
---|---|---|
filter(Predicate) | 过滤 , 筛选 | Stream<T> |
sorted(Comparator) | 排序 | Stream<T> |
distinct() | 去重 | Stream<T> |
limit(int) | 取前几个元素 | Stream<T> |
skip(int) | 跳过前几个元素 | Stream<T> |
map(Function<T,R>) | 将流中的每个元素利用函数映射为另一个元素 | Stream<R> |
终端操作Stream<T>
方法 | 作用 | 返回值 |
---|---|---|
count() | 返回元素的个数 | long |
forEach(Consumer) | 遍历Stream中的所有元素 | void |
max(Comparator) / min(Comparator) | 找最大/最小的元素 | Optional<T> |
findAny() | 找到Stream中的某个对象 | Optional<T> |
findFirst() | 找到Stream中的第一个对象 | Optional<T> |
allMatch(Predicate) | 判断流中的元素是否都匹配条件 | boolean |
anyMatch(Predicate) | 判断流中得到元素是否有一个能匹配条件 | boolean |
noneMatch(Predicate) | 判断流中的元素是否都不能匹配条件 | boolean |
collect(Collector<T,A,R>) | 收集流中的元素 | R |
R collect(Collector) Collector: 收集器 <T,A,R> 将Stream<T> 转化收集最终成为 R对象
Collectors 工具类, 可以得到常用的各种Collector
3.Collectors中的常用静态方法
1.
public static <T> Collector<T,?,List<T>> toList() 将流中的所有对象放入List 返回:List<T>
案例: List<Student> result = students.stream().collect( Collectors.toList() );
2.
public static <T> Collector<T,?,Double> averagingInt(ToIntFunction<? super T> mapper)
将若干int数据计算平均值 返回值: Double
案例: double result = students.stream().collect(Collectors.averagingInt(Student::getScore));
3.
public static <T> Collector<T,?,Integer> summingInt(ToIntFunction<? super T> mapper)
将若干int数组计算和 返回值 int
4.
public static <T> Collector<T,?,Optional<T>> maxBy(Comparator<? super T> comparator)
求所有对象的最大值 返回值 Optional<T>
5.
public static <T> Collector<T,?,IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper)
求若干int的数量, 最大值, 最小值 总和 , 平均值
案例: IntSummaryStatistics result = students.stream().
collect(Collectors.summarizingInt(Student::getScore));
System.out.println(result.getCount());
System.out.println(result.getMax());
System.out.println(result.getMin());
System.out.println(result.getSum());
System.out.println(result.getAverage());
6.
public static Collector<CharSequence,?,String> joining(CharSequence delimiter)
将流中的所有对象拼成String , delemiter作为分隔符
案例: List<String> list= Arrays.asList("Liudd","Wangdd","Yangdd","Hudd");
String result = list.stream().collect(Collectors.joining(","));
System.out.println(result);
7.
public static <T,K> Collector<T,?,Map<K,List<T>>> groupingBy(Function<T, K> classifier)
将流中的对象,按Function中的结果K,做分组, 元素分别放入List中 返回值: Map<K,List<T>>
案例: Map<String,List<Student>> result = students.stream().collect(groupingBy(Student::getClassNumber));
8.
public static <T,K,A,D> Collector<T,?,Map<K,D>> groupingBy(Function<T,K> classifier, Collector<T,A,D> downstream)
将流中的对象,按Function中的结果K,做分组, 再把分组的元素利用downstream
收集为D对象,作为Map的值 返回值: Map<K,D>
案例: Map<String,Double> result = students.stream().collect(
groupingBy(Student::getClassNumber,averagingInt(Student::getScore)
));
result.forEach((s,d)->System.out.println(s+":"+d));
9.
public static <T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream,
Function<R,RR> finisher)
先利用downstream做数据收集, 结果R, 然后将收集的R数据利用finisher函数转换为RR对象
案例: Student s = students.stream()
.collect(collectingAndThen(maxBy(comparing(Student::getScore)),Optional::get));
10.
public static <T,U,A,R> Collector<T,?,R> mapping(Function<T, U> mapper,
Collector<U,A,R> downstream)
先利用函数 将流中的T对象,转换为U对象, 再利用downstream,将U对象收集为R对象
案例: String result = students.stream().collect(mapping(Student::getName, joining(",")));
11.
public static <T,D,A> Collector<T,?,Map<Boolean,D>> partitioningBy
(Predicate<T> predicate, Collector<T,A,D> downstream)
先利用谓词,将流中的对象按true,false分为两组,
再将每组的对象利用downstream收集为D对象,放入map
案例: Map<Boolean,Double> result = students.stream().collect(partitioningBy
(Student::isMale,averagingInt(Student::getScore)));