Java 8 Lambda使用

Lambda

介绍

Lambda 表达式是 JDK8 的一个新特性,可以取代大部分的匿名内部类,写出更优雅的 Java 代码,尤其在集合的遍历和其他集合操作中,可以极大地优化代码结构。

本质

Lambda表达式本质是函数式接口的实例

函数式接口

函数式接口定义

只定义了一个抽象方法,那它就是一个函数式接口,哪怕这个接口有好多默认的方法实现,如Comparator接口类

只要接口定义了一个抽象方法,那它就是一个函数式接口,还有在上述Java Api中都有个@FunctionalInterface注解,这表示着该接口会设计成一个函数式接口,不符合规范的话,就会编译报错。

stream

首先,Stream流有一些特性:
Stream流不是一种数据结构,不保存数据,它只是在原数据集上定义了一组操作。
这些操作是惰性的,即每当访问到流中的一个元素,才会在此元素上执行这一系列操作。
Stream不保存数据,故每个Stream流只能使用一次。
关于应用在Stream流上的操作,可以分成两种:Intermediate(中间操作)和Terminal(终止操作)。中间操作的返回结果都是Stream,故可以多个中间操作叠加;终止操作用于返回我们最终需要的数据,只能有一个终止操作。

流是惰性的,即每当用到一个元素时,才会在这个元素上执行这一系列操作。

流的Intermediate方法(中间操作)

filter(Predicate)
将结果为false的元素过滤掉
map(fun)
转换元素的值,可以用方法引元或者lambda表达式
flatMap(fun)
若元素是流,将流摊平为正常元素,再进行元素转换
limit(n)
保留前n个元素
skip(n)
跳过前n个元素
distinct()
剔除重复元素
sorted()
将Comparable元素的流排序
sorted(Comparator)
将流元素按Comparator排序

流的Terminal方法(终结操作)

约简操作
max(Comparator)
min(Comparator)
count()
findFirst()
返回第一个元素
findAny()
返回任意元素
anyMatch(Predicate)
任意元素匹配时返回true
allMatch(Predicate)
所有元素匹配时返回true
noneMatch(Predicate)
没有元素匹配时返回true
reduce(fun)
从流中计算某个值,接受一个二元函数作为累积器,从前两个元素开始持续应用它,累积器的中间结果作为第一个参数,流元素作为第二个参数
reduce(a, fun)
a为幺元值,作为累积器的起点
reduce(a, fun1, fun2)
与二元变形类似,并发操作中,当累积器的第一个参数与第二个参数都为流元素类型时,可以对各个中间结果也应用累积器进行合并,但是当累积器的第一个参数不是流元素类型而是类型T的时候,各个中间结果也为类型T,需要fun2来将各个中间结果进行合并
收集操作
iterator()
forEach(fun)
forEachOrdered(fun)
可以应用在并行流上以保持元素顺序
toArray()
toArray(T[] :: new)
返回正确的元素类型
collect(Collector)
collect(fun1, fun2, fun3)
fun1转换流元素;fun2为累积器,将fun1的转换结果累积起来;fun3为组合器,将并行处理过程中累积器的各个结果组合起来

filter

将结果为false的元素过滤掉

Stream<Person> personStream = collection.stream().filter( person -> "男".equals(person.getGender())//只保留男性 );


filter(s->s.getGender() && s.getHeight() >= 1.8)

map

map进行对于Stream中包含的元素使用给定的转换函数进行转换操作

调用方法:
menuCatalogVOList = menuList.stream().filter(menu -> menu.getMenuGrade()==1).map(this::copyProperties).sorted(Comparator.comparing(MenuCatalogVO::getMenuSort)).collect(Collectors.toList());



//将Employee 转换 Leader 列表
        List<Leader> leaders = list.stream().filter(employee -> employee.getSalary() == 2000).map(employee -> {
    
    
            Leader leader = new Leader();
            leader.setName(employee.getName());
            leader.setSalary(employee.getSalary());
            return leader;
})

sorted

自然排序

sorted() 默认使用自然序排序, 其中的元素必须实现Comparable 接口

例子:
实体类:

public class Student implements Comparable<Student> {
    
     
private int id; 
private String name; 
private int age; 
public Student(int id, String name, int age) {
    
     
this.id = id; this.name = name; this.age = age; 
}
 public int getId() {
    
     
return id; 
} 
public String getName() {
    
    
 return name; 
} 
public int getAge() {
    
     
return age;
 } 
@Override
public int compareTo(Student ob) {
    
     
return name.compareTo(ob.getName());
} 
@Override
public boolean equals(final Object obj) {
    
     
if (obj == null) {
    
    
 return false; 
} 
final Student std = (Student) obj;
 if (this == std) {
    
     
return true; 
}else {
    
     
return (this.name.equals(std.name) && (this.age == std.age)); 
} 
} 
@Override public int hashCode() {
    
     
int hashno = 7; hashno = 13 * hashno + (name == null ? 0 : name.hashCode()); return hashno; 
} 
}
升序
List<Student> list = new ArrayList<Student>(); 
list.add(new Student(1, "Mahesh", 12));
 list.add(new Student(2, "Suresh", 15)); 
list.add(new Student(3, "Nilesh", 10)); 
System.out.println("---Natural Sorting by Name---");
List<Student> slist = list.stream().sorted().collect(Collectors.toList()); slist.forEach(e -> System.out.println("Id:"+ e.getId()+", Name: "+e.getName()+", Age:"+e.getAge()));

倒序
System.out.println("---Natural Sorting by Name in reverse order---"); slist = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()); slist.forEach(e -> System.out.println("Id:"+ e.getId()+", Name: "+e.getName()+", Age:"+e.getAge()));

自定义排序

sorted(Comparator<? super T> comparator) :我们可以使用lambada 来创建一个Comparator 实例。可以按照升序或着降序来排序元素。
升序

System.out.println("---Sorting using Comparator by Age---"); 
slist = list.stream().sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList()); slist.forEach(e>System.out.println("Id:"+e.getId()+",Name:"+e.getName()+",Age:"+e.getAge()));

降序

System.out.println("---Sorting using Comparator by Age with reverse order---"); 
slist=list.stream().sorted(Comparator.comparing(Student::getAge).reversed()).collect(Collectors.toList()); slist.forEach(e -> System.out.println("Id:"+ e.getId()+", Name: "+e.getName()+", Age:"+e.getAge()));

使用Stream进行多字段排序

list.stream() .sorted(Comparator.comparing(Tt::getId)).sorted(Comparator.comparing(Tt::getLine)) .collect(Collectors.toList());

根据理论,应该是先根据id去排好序,再根据行号去排号序,结果是按后者顺序打印的

由此推断出,当需要用到stram多条件排序的时候,需要最后排序的字段需要放在前面排

list.stream() .sorted(Comparator.comparing(Tt::getLine)).sorted(Comparator.comparing(Tt::getId)) .collect(Collectors.toList());

Collector

collect(Collector)
1.求值
averaging操作可以计算输入元素的均值,该操作包括三个方法:
Collector<T, ?, Double> averagingInt(ToIntFunction<? super T> mapper)
Collector<T, ?, Double> averagingLong(ToLongFunction<? super T> mapper)
Collector<T, ?, Double> averagingDouble(ToDoubleFunction<? super T> mapper)

.collect(Collectors.averagingInt(Apple::getWeight))

2.均值:averaging

3.元素个数:counting

4.maxBy和minBy操作可以找出输入元素中的最大最小值
Collector<T, ?, Optional> minBy(Comparator<? super T> comparator)
Collector<T, ?, Optional> maxBy(Comparator<? super T> comparator)

.collect(Collectors.maxBy(Comparator.comparingInt(Apple::getWeight)))

猜你喜欢

转载自blog.csdn.net/weixin_42371621/article/details/109177431