
@Test
void test1() {
List str = Arrays.asList("d", "a", "b", "e", "c", "a");
// 老版本字符串排序
Collections.sort(str, new Comparator() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
// 使用Lambda字符串排序
str.sort((a, b) -> a.compareTo(b));
System.out.println("java8字符串串排序:" + str);
// 使用lambda启动线程
new Thread(() -> System.out.println("线程启动")).start();
}
输出结果:
java8字符串串排序:[a, a, b, c, d, e] 线程启动2.Stream 2.1 forEach
@Test
void test2() {
List students = Arrays.asList(
new Student("1", "a", "18"),
new Student("1", "a", "18"),
new Student("3", "c", "30"),
new Student("3", "e", "19"));
// forEach
students.stream().forEach(System.out::println); // :: 方法的引用
System.out.println("--------------------");
students.stream().forEach(e -> System.out.println(e));
}
输出结果:
Student{id='1', name='a', age='18', isBoy=false}
Student{id='1', name='a', age='18', isBoy=false}
Student{id='3', name='c', age='30', isBoy=false}
Student{id='3', name='e', age='19', isBoy=false}
--------------------
Student{id='1', name='a', age='18', isBoy=false}
Student{id='1', name='a', age='18', isBoy=false}
Student{id='3', name='c', age='30', isBoy=false}
Student{id='3', name='e', age='19', isBoy=false}
2.2 filter过滤操作
@Test
void test3() {
List a = students.stream().filter(e -> e.getName().equals("a")).collect(Collectors.toList());
System.out.println("过滤name为a=" + a);
students.get(0).setBoy(true);
List collect5 = students.stream().filter(Student::isBoy).collect(Collectors.toList());
System.out.println("过滤是男孩的=" + collect5);
}
Streamfilter(Predicate super T> predicate);
由源码可知 filter 接受 Predicate断言型函数即可判断真假,后面会讲解Java自带的四大内置函数
输出结果:
过滤name为a=[Student{id='1', name='a', age='18', isBoy=false}, Student{id='1', name='a', age='18', isBoy=false}]
过滤是男孩的=[Student{id='1', name='a', age='18', isBoy=true}]
2.3 sorted 排序
@Test
void test4() {
// sorted 排序,如果不指定Comparator将按照默认方式排序
// 按照学生id降序,姓名升序,年龄升序排列comparing
List collect = students.stream().sorted(Comparator.comparing(Student::getId).reversed().thenComparing(Student::getName).thenComparing(Student::getAge)).collect(Collectors.toList());
System.out.println("排序=" + collect);
}
输出结果:
排序=[Student{id='3', name='c', age='30', isBoy=false}, Student{id='3', name='e', age='19', isBoy=false}, Student{id='1', name='a', age='18', isBoy=false}, Student{id='1', name='a', age='18', isBoy=false}]
2.4 map 映射,将元素转成另外的对象
@Test
void test5() {
// map 映射,将元素转成另外的对象
List collect1 = str.stream().map(String::toUpperCase).collect(Collectors.toList());
System.out.println("转换成大写=" + collect1);
}
输出结果:
转换成大写=[D, A, B, E, C, A]2.5 count ,max ,min,sum
@Test
void test6() {
// count 统计
long count = students.stream().count();
System.out.println("统计=" + count);
// 最值 max,min,sum
Student student = students.stream().max(Comparator.comparing(Student::getAge)).get();
Student student2 = students.stream().min(Comparator.comparing(e -> e.getAge())).get();
int sumAge = students.stream().mapToInt(e -> Integer.valueOf(e.getAge())).sum();
System.out.println("年龄最大的学生=" + student);
System.out.println("年龄最小的学生=" + student2);
System.out.println("年龄求和=" + sumAge);
}
输出结果:
统计=4
年龄最大的学生=Student{id='3', name='c', age='30', isBoy=false}
年龄最小的学生=Student{id='1', name='a', age='18', isBoy=false}
年龄求和=85
2.6 reduce 规约操作,distinct字符串去重,skip 跳过
@Test
void test7() {
// reduce 规约操作
double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min); // 取最小值
System.out.println("最小值=" + minValue);
// distinct 字符串去重
List collect2 = str.stream().distinct().collect(Collectors.toList());
System.out.println("字符串去重=" + collect2);
// skip 跳过
List collect3 = students.stream().skip(2).collect(Collectors.toList());
System.out.println("跳过前两个元素=" + collect3);
}
输出结果:
最小值=-3.0
字符串去重=[d, a, b, e, c]
跳过前两个元素=[Student{id='3', name='c', age='30', isBoy=false}, Student{id='3', name='e', age='19', isBoy=false}]
2.7 对象去重多种方式
@Test
void test8() {
// 以id去重
TreeSet students1 = new TreeSet<>(Comparator.comparing(Student::getId));
students1.addAll(students);
List students2 = new ArrayList<>(students1);
System.out.println("根据id去重方式1=" + students2);
TreeSet collect7 = students.stream().collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getId))));
System.out.println("根据id去重方式2=" + collect7);
// collectingAndThen 对归纳的结果进行二次处理
ArrayList collect6 = students.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getId))), ArrayList::new));
System.out.println("根据id去重方式3=" + collect6);
ArrayList collect8 = students.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(e -> e.getId() + "," + e.getName()))), ArrayList::new));
System.out.println("根据id和名字去重=" + collect8);
}
输出结果:
根据id去重方式1=[Student{id='1', name='a', age='18', isBoy=false}, Student{id='3', name='c', age='30', isBoy=false}]
根据id去重方式2=[Student{id='1', name='a', age='18', isBoy=false}, Student{id='3', name='c', age='30', isBoy=false}]
根据id去重方式3=[Student{id='1', name='a', age='18', isBoy=false}, Student{id='3', name='c', age='30', isBoy=false}]
根据id和名字去重=[Student{id='1', name='a', age='18', isBoy=false}, Student{id='3', name='c', age='30', isBoy=false}, Student{id='3', name='e', age='19', isBoy=false}]
2.8 groupingBy 分组
@Test
void test9() {
// groupingBy 分组
Map> collect4 = students.stream().collect(Collectors.groupingBy(Student::getId));
System.out.println("根据id分组=" + collect4);
}
输出结果:
根据id分组={1=[Student{id='1', name='a', age='18', isBoy=false}, Student{id='1', name='a', age='18', isBoy=false}], 3=[Student{id='3', name='c', age='30', isBoy=false}, Student{id='3', name='e', age='19', isBoy=false}]}
3.Optional
3.1 Optional三种创建方式
Optional在实际开发中常用于判空操作
@Test
void test10() {
//Optional 三种创建optional方式
Optional
输出结果:
a a3.2 ifPresent 是否存在
@Test
void test11() {
students.stream().forEach(e -> {
Optional id = Optional.ofNullable(e).map(Student::getId);
id.ifPresent(v -> System.out.println("获取id:" + v));
});
}
输出结果:
获取id:1 获取id:1 获取id:3 获取id:3
学生类
public class Student {
private String id;
private String name;
private String age;
//boolean 默认值为false Boolean 默认值为null
private boolean isBoy;
// 省去get/set方法
}
4.Java8内置的函数式接口
4.1 消费型接口
4.2 供给型接口Consumer 接口只有一个抽象方法 accept,参数列表只有一个泛型t,无返回值,重点在于内部消费
4.3 函数型接口Supplier 只有一个抽象方法 get,参数列表为空,有返回值,返回值得数据类型为T
4.4 断言型接口Function
只有一个抽象方法名为 apply,参数列表只有一个参数为T,有返回值,返回值的数据类型为R
断言型又名判断型。 Predicate 只有一个抽象方法 test,参数列表只有一个参数为 T,有返回值,返回值类型为 boolean