Lambda表达式是一个匿名函数,运用Lambda表达式可以极大的提高编程效率和程序可读性。
Java 8 中的 Stream 是对集合(Collection)对象功能的增强,对集合进行各种非常便利、高效的聚合操作,或者大批量数据操作。
Stream 可以理解为高级版本的 Iterator。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用 fork/join 并行方式来拆分任务和加速处理过程。
(str) -> System.out.println(str)
左边代表参数,右边代表主体。
(str) :代表参数,不写类型会根据上下文获取(str1),也可以自己定义参数(String str1),也可以有多个参数(String str1,String str2),也可以无参()。
-> : 理解为“转到”的意思
System.out.println(str) : 代表主体,如果是代码块加上花括号{System.out.println(str1); System.out.println(str2);}
废话少说,下面介绍下在项目中经常用到的Lamdba表达式
代替匿名内部类
//before
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("123");
}
}).start();
//after
new Thread(() -> System.out.println("456")).start();
forEach:循环List
List list = Arrays.asList("2", "b", "10", "4", "6", "aa", "b", "ccdf");
//before
for (String str : list) {
System.out.println(str);
}
//after
list.forEach((str) -> System.out.println(str));
// double colon operator
list.forEach(System.out::println);
System.out.println("**********************************************");
//before
for (String str : list) {
if (str.equals("a")) {
System.out.println(str);
}
}
//after
list.forEach((str) -> {
if (str.equals("a")) {
System.out.println(str);
}
});
sort : 对List进行排序
List list = Arrays.asList("2", "b", "10", "4", "6", "aa", "b", "ccdf");
//before
Collections.sort(list, new Comparator() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
//after
Comparator sortByName = ((String s1, String s2) -> (s1.compareTo(s2)));
list.sort(sortByName);
//or
list.sort((String s1, String s2) -> s1.compareTo(s2));
map : 它的作用就是把 input Stream 的每一个元素,映射成 output Stream 的另外一个元素。
List list = Arrays.asList("a", "a", "b", "c", "d", "g", "a", "z", "c");
//转换成大写
List output = list
.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(output);
//每个元素 都 加上"字母"
List collect = list
.stream()
.map(s -> s + "字母")
.collect(Collectors.toList());
System.out.println(collect);
reduce : 依照运算规则把 Stream 里所有的元素组合起来
List list = Arrays.asList("a", "a", "b", "c", "d", "g", "a", "z", "c");
// 把字符串都连接在一起
String reduce = list.stream().reduce("",String::concat);
System.out.println(reduce);
// 求最小值
double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min);
System.out.println(minValue);
// 求和,有起始值
int sumValue = Stream.of(1, 2, 3, 4).reduce(10, Integer::sum);
System.out.println(sumValue);
// 求和,无起始值
sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();
System.out.println(sumValue);
下面我们建一个实体类,进一步学习
class Student {
private int id;
private String name;
private int age;
private String gender;
//getter \ setter 构造器 省略
}
Collectors.groupingBy : 把 Stream 元素进行归组
Collectors.partitioningBy 其实是一种特殊的 groupingBy
List list = Arrays.asList("a", "a", "b", "c", "d", "g", "a", "z", "c");
//统计每个字母出现次数
Map collect = list.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(collect);
System.out.println("**********************************************");
//初始化测试数据
List studentList = new ArrayList() {
{
add(new Student(1, "小明", 12, "男"));
add(new Student(2, "小花", 18, "女"));
add(new Student(3, "小白", 13, "女"));
add(new Student(4, "小黑", 14, "男"));
}
};
// 按照年龄进行分组
Map> baby = studentList
.stream()
.collect(Collectors.partitioningBy(s -> s.getAge() < 18));
System.out.println("年龄小于18的人数: " + baby.get(true).size());
System.out.println("年龄大于18的人数: " + baby.get(false).size());
// 按照性别分组 返回集合对象
Map> collect1 = studentList
.stream()
.collect(Collectors.groupingBy(Student::getGender));
System.out.println(collect1);
//按照性别分组 返回统计后的个数
Map collect2 = studentList
.stream()
.collect(Collectors.groupingBy(Student::getGender, Collectors.counting()));
System.out.println(collect2);
filter 、collect 、map 、limit 等等操作
//初始化测试数据
List studentList = new ArrayList() {
{
add(new Student(1, "小明", 12, "男"));
add(new Student(2, "小花", 18, "女"));
add(new Student(3, "小白", 13, "女"));
add(new Student(4, "小黑", 14, "男"));
}
};
//查出所有学生姓名
studentList.forEach((s) -> System.out.println(s.getName()));
System.out.println("**********************************************");
//给所有的学生年龄加3岁
Consumer studentConsumer = s -> s.setAge(s.getAge() + 3);
studentList.forEach(studentConsumer);
System.out.println(studentList);
System.out.println("**********************************************");
//使用过滤器filter ,查出小明的信息
studentList.stream().filter((s) -> s.getName().equals("小明")).forEach((s) -> System.out.println(s));
System.out.println("**********************************************");
// 自定义一些 filter
Predicate nameFilter = (s) -> s.getName().equals("小花");
Predicate ageFliter = (s) -> s.getAge() > 10;
studentList.stream().filter(nameFilter).filter(ageFliter).forEach(System.out::println);
System.out.println("**********************************************");
//limit 限制返回结果的个数
studentList.stream().filter(ageFliter).limit(2).forEach(System.out::println);
System.out.println("**********************************************");
//排序sorted + 转换collect
List collect = studentList
.stream()
.sorted((s1, s2) -> s1.getAge() - s2.getAge())
.collect(Collectors.toList());
System.out.println(collect);
System.out.println("**********************************************");
//获取最大 \ 最小 年龄
Student studentMax = studentList
.stream()
.min((s1, s2) -> s1.getAge() - s2.getAge())
//.max((s1, s2) -> s1.getAge() - s2.getAge())
.get();
System.out.println(studentMax);
System.out.println("**********************************************");
// map + collect 将结果集转成String 、 Set ...
String studentNameStr = studentList
.stream()
.map(Student::getName)
.collect(Collectors.joining(","));
System.out.println(studentNameStr);
Set studentNameSet = studentList
.stream()
.map(Student::getName)
.collect(Collectors.toSet());
System.out.println(studentNameSet);
System.out.println("**********************************************");
//统计所有学生的年龄总和
int sum = studentList
.parallelStream()
.mapToInt(s -> s.getAge())
.sum();
System.out.println(sum);
List list = new ArrayList<>();
list.stream().collect(Collectors.toMap(User::getId, User::getName));
list.stream().collect(Collectors.toMap(User::getId, s -> s));
参考文章: https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/