一、Lambda表达式
Lambda表达式常用场景:
/**
* 一、使用lambdas 来实现 Runnable接口:() ->
* 二、使用Lambdas【排序】集合:
* (根据集合中对象的年龄,名字的最后一个字母排序:Arrays.sort(表达式)/ sorted())
* 描述:①使用 Arrays.sort(list,(String s1,String s2)->(s1.compareTo(s2)));
* ②使用 list.stream()
* .sorted((o1, o2) -> (o1.getSalary() - o2.getSalary()))
* .collect(Collectors.toList());
* 三、使用forEach【循环】集合:list.forEach(表达式)
* (修改集合中对象的属性(如薪资加5%)、获取集合中对象某一属性的集合、获取与集合中对象多个属性相同的对象的集合))
* 描述:① 集合.forEach(对象->对象处理(如打印对象、修改集合中对象的属性(如薪资加5%)、获取集合中对象某一属性的集合、获取与集合中对象多个属性相同的对象的集合));
* ② 使用双冒号操作符("pojo类名::方法名" 表示:"pojo类中的此get方法")
* ①list.forEach(people -> people.setSalary(people.getSalary()+people.getSalary()/100*5));
* ②List<Integer> ageLists=new ArrayList<>();
peopleList.forEach(people -> {
ageLists.add(people.getAge());
});
③List<Person> personList=new ArrayList<>();
peopleList.forEach(people -> {
Person per=new Person();
per.setAge(people.getAge());
per.setFirstName(people.getFirstName());
personList.add(per);
});
* 四、使用Lambdas和Streams:
* (①filter()过滤器(Predicate):获取月薪超过1400的员工信息;
* ②reduce()可理解为数值计算;
* ③limit()限制结果集(sorted()排序);
* ④map()修改list集合中元素的属性。)
* 描述:返回List
* list.stream().filter(表达式).collect(Collectors.toList()); 筛选集合元素;
* list.stream().map(表达式).collect(Collectors.toList());
* list.parallelStream().map(表达式).collect(Collectors.toList());
* 描述:reduce()可理解为数值计算
* list.stream().reduce(表达式);
* 描述:返回Map
* list.stream().collect(Collectors.groupingBy(表达式));
* 描述:返回String
* list.stream().map(表达式).collect(Collectors.joining("..."));
* ①list.stream()
.filter(people -> people.getSalary()>1400)
.limit(3)
.collect(Collectors.toList());
②map示例见下1.1(修改集合中元素属性):
(详情见下!)
* */
参考一:JAVA8-LAMBDA中reduce的用法:https://blog.csdn.net/zhang89xiao/article/details/77164866
参考二:https://blog.csdn.net/hu10131013/article/details/108368809
(详情参考项目代码!)
1.1 将一个集合的所有属性值赋给另一个集合 使用Lambda表达式:
方式一: 先将一个类的所有属性值赋给另一个类:(可使用方法二中 BeanUtils.copyProperties());
再调用此方法:List.stream().map(对象::方法名).collect(Collectors.toList());
List<FileUploadResult> uploadResults=FileUploadRecordList.stream()
.map(this::convertToFileUploadRecord)
.collect(Collectors.toList());
方式二: 直接使用Lambda表达式: list.stream().map(表达式).collect(Collectors.toList());
1.2 过滤掉集合中没有元素的空集合使用Lambda表达式: list.stream().filter(表达式).collect(Collectors.toList());
files = files.stream().filter(file -> file.getSize() != 0).collect(Collectors.toList());
一、使用lambdas 来实现 Runnable接口:() ->
/*【1.1】以前的循环方式*/
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello!");
}
}).start();
/*【1.2】使用lambdas */
new Thread(() -> System.out.println("Hello!")).start();
/*【2.1】使用匿名内部类*/
Runnable run1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello!");
}
};
/*【2.2】使用lambdas */
Runnable run2 = () -> {
System.out.println("Hello!");
};
// 直接调用 run 方法(没开新线程!)
run1.run();
run2.run();
二、使用Lambdas排序集合
String[] players2 = {"Rafael Nadal", "Novak Djokovic","John Isner"};
//0. 将peopleList集合按照'name的最后一个字母'排序
peopleList.sort((p1,p2) -> Integer.valueOf(p1.getSalary())-Integer.valueOf(p2.getSalary()));
//1. 将players集合按照'name'排序
/*【1.1】使用匿名内部类根据 name 排序 players */
Arrays.sort(players2, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
});
/*【1.2】使用lambdas排序: */
Arrays.sort(players2,(String s1,String s2)->(s1.compareTo(s2)));
//2. 将players集合按照'name的length'排序
/*【2.1】使用匿名内部类根据 name的length 排序 players */
Arrays.sort(players2, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.length()-s2.length();
}
});
/*【2.2】使用lambdas排序: */
Arrays.sort(players2,(String s1,String s2)->(s1.length()-s2.length()));
//3. 将players集合按照'name的最后一个字母'排序
/*【3.1】使用匿名内部类根据 name的最后一个字母 排序 players */
Arrays.sort(players2, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.charAt(s1.length()-1)- s2.charAt(s2.length()-1);
}
});
/*【3.2】使用lambdas排序: */
Arrays.sort(players2,(String s1,String s2)->s1.charAt(s1.length()-1)-s2.charAt(s2.length()-1));
三、使用forEach【循环】集合:list.forEach(表达式)
描述:
① 集合.forEach(对象->对象处理(如打印对象、修改集合中元素某一属性(如薪资加5%)、获取对象年龄属性add到另一list中、获取对象多个属性set到新对象中再add新对象到新的list中));
② 使用双冒号操作符(“pojo类名::方法名” 表示:“pojo类中的此get方法”)
//以前的循环方式
for (People pe : peopleList) {
System.out.println(pe);
}
//1.打印每个people信息
peopleList.forEach(people -> System.out.println(people));//使用 lambda 表达式以及函数操作
peopleList.forEach(System.out::println);//在 Java 8 中使用双冒号操作符("pojo类名::方法名"表示"pojo类中的此get方法")
//2.将员工薪资增加5%
peopleList.forEach(people -> people.setSalary(people.getSalary()+people.getSalary()/100*5));
//3.获取对象年龄属性add到另一list中
List<Integer> ageLists=new ArrayList<>();
peopleList.forEach(people -> {
ageLists.add(people.getAge());
});
//4.获取对象多个属性set到新对象中再add新对象到新的list中
List<Person> personList=new ArrayList<>();
peopleList.forEach(people -> {
Person per=new Person();
per.setAge(people.getAge());
per.setFirstName(people.getFirstName());
personList.add(per);
});
四、使用Lambdas和Streams:
描述:返回List
list.stream().filter(表达式).collect(Collectors.toList()); 筛选集合元素;
list.stream().map(表达式).collect(Collectors.toList());
list.parallelStream().map(表达式).collect(Collectors.toList());
//1.【过滤器filter】
//1.1获取peopleList中'工资为1000且名字为Jay'的元素的集合(list)
List<People> list =peopleList.stream()
.filter(people -> people.getSalary() == 1000 && people.getFirstName().equals("Jay"))
.collect(Collectors.toList());
//1.2打印月薪超过1400的员工信息
peopleList.stream()
.filter(people -> people.getSalary()>1400)
.forEach(people -> System.out.println(people));
/*我们也可以定义过滤器,然后重用它们来执行其他操作:*/
//定义filter
Predicate<People> ageFilter = p -> (p.getAge() > 25);
Predicate<People> salaryFilter = p -> (p.getSalary() > 1400);
Predicate<People> genderFilter = p -> ("female".equals(p.getGender()));
System.out.println("下面是年龄大于 24岁且月薪在$1,400以上的女程序员:");
peopleList.stream()
.filter(ageFilter.and(salaryFilter).and(genderFilter))
.forEach(p -> System.out.println(p));
/*javaProgrammers.stream()
.filter(ageFilter)
.filter(salaryFilter)
.filter(genderFilter)
.forEach(p-> System.out.println(p));
.filter(ageFilter)*/
// 重用filters
System.out.println("年龄大于 24岁的女性 Java programmers:");
peopleList.stream()
.filter(genderFilter)
.forEach(p -> System.out.println(p));
//2.获取numbers1中'元素的平方数'的集合(squaresList)(技巧:看".map( i -> i*i)"中做了什么)
List<Integer> numbers1 = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
List<Integer> squaresList = numbers1.stream()
.map( i -> i*i).distinct()
.collect(Collectors.toList());
//2.1 获取与peopleList中(vo)元素对象的"全部属性值"完全相同的(p)对象的集合(将vo的属性复制给p)
List<People> peopleList2 = peopleList.parallelStream()
.map(vo -> {
People p = new People();
BeanUtils.copyProperties(vo, p);
return p;
})
.collect(Collectors.toList());
//2.2 获取与peopleList中(vo)元素对象的"工资"相同的(p)对象的集合(peopleList3)
List<People> peopleList3 = peopleList.stream()
.map(vo -> {
People p = new People();
p.setSalary(vo.getSalary());
return p;
})
.collect(Collectors.toList());
//2.3 获取与peopleList中(vo)元素对象的"firstName+lastName再赋值给firstName"的对象的集合(peopleList3)
//即将peopleList中所有元素的'firstName'重新改为'firstName+lastName'(修改原集合中对象的属性)
List<People> peopleList4 = peopleList.stream()
.map(people -> {
String firstName = people.getFirstName();
String lastName = people.getLastName();
String name = firstName + lastName;
people.setFirstName(name);
return people;
})
.collect(Collectors.toList());
/**
* 3.list.stream().reduce(表达式);
* JAVA8-LAMBDA中reduce的用法:https://blog.csdn.net/zhang89xiao/article/details/77164866、
* 描述:reduce()可理解为数值计算
*/
//list.stream().reduce(表达式),返回Optional;
Optional<People> optional = peopleList.stream()
.reduce((to, bo) -> {
int s = to.getSalary();
int u = bo.getSalary();
to.setSalary(s + u);
return to;
});
Map<String, String> map = new HashMap<>();
if (optional.isPresent()) {
People po = optional.get();
map.put("1", po.getFirstName());
}
/**
* 4.list.stream().collect(Collectors.groupingBy(表达式));
描述:返回Map
*/
//4.1 将peopleList按照对象的年龄进行分组
Map<Integer, List<People>> groupMap = peopleList.stream()
.collect(Collectors.groupingBy(t -> t.getAge()));
//4.2 将peopleList按照对象的firstName进行分组【"People::getFirstName" 表示 "People中的getFirstName方法"】
Map<String, List<People>> otherMap = peopleList.stream()
.peek(peo -> {
peo.setAge(90);
})
.collect(Collectors.groupingBy(People::getFirstName));
/**
* 5.list.stream().map(表达式).collect(Collectors.joining("..."));
描述:返回String。
*/
//将peopleList集合元素连接成字符串,元素间用","隔开。
String str = peopleList.stream()
.map(po -> {
return po == null ? "null" : po.getFirstName() + ":" + po.getAge();
})
.collect(Collectors.joining(","));
/**
* 6.list.sort(表达式);
描述:排序
*/
peopleList.sort((p1, p2) -> Integer.valueOf(p1.getSalary() - Integer.valueOf(p2.getSalary())));
【六】、limit方法:
/* (filter过滤后)使用limit方法,可以限制结果集的个数: */
System.out.println("最前面的3个女性 Java programmers:");
peopleList.stream()
.filter(ageFilter.and(salaryFilter))
.limit(3)
.forEach(p -> System.out.println(p));
【七】、sorted方法:
/*根据名字和薪水排序Java程序员,放到一个list中,然后显示列表:用collect-toList()*/
System.out.println("根据 name 排序,并显示前5个 Java programmers:");
List<People> sortedJavaProgrammers = peopleList.stream()
.sorted((o1, o2) -> (o1.getFirstName().compareTo(o2.getFirstName())))
.limit(5)
.collect(Collectors.toList());
System.out.println("根据 salary 排序 Java programmers:");
List<People> sortedJavaProgrammersBySalary = peopleList.stream()
.sorted((o1, o2) -> (o1.getSalary() - o2.getSalary()))
.collect(Collectors.toList());
【八】、map方法:
/*上面的例子中我们已经看到 collect 方法是如何工作的。 结合 map 方法,我们可以使用 collect 方法
来将我们的结果集放到一个字符串,一个 Set 或一个TreeSet中:*/
System.out.println("将 Java programmers 的 first name 拼接成字符串:用collect-joining()");
String javaDevelopers = peopleList.stream()
.map(People::getFirstName)
.collect(Collectors.joining(";"));
System.out.println("将 Java programmers 的 first name 存放到 Set:用collect-toSet()");
Set<String> javaDevFirstName = peopleList.stream()
.map(People::getFirstName)
.collect(toSet());
【九】、map方法:
/*Streams 还可以是并行的(parallel)。 示例如下:*/
System.out.println("计算付给 Java programmers 的所有money:");
int totalSalary = peopleList
.parallelStream()
.mapToInt(p -> p.getSalary())
.sum();
/*我们可以使用summaryStatistics方法获得stream 中元素的各种汇总数据。
接下来,我们可以访问这些方法,比如getMax, getMin, getSum或getAverage:*/
//计算 count, min, max, sum, and average for numbers
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
IntSummaryStatistics sumnum = numbers.stream()
.mapToInt(p -> p)
.summaryStatistics();
System.out.println("List中最大的数字 : " + sumnum.getMax());
System.out.println("List中最小的数字 : " + sumnum.getMin());
System.out.println("所有数字的总和 : " + sumnum.getSum());
System.out.println("所有数字的平均值 : " + sumnum.getAverage());