一.定义对象和方法
@Data
@AllArgsConstructor
public class TestVo {
private String name;
private Integer age;
private double height;
}
private static void testPrint(TestVo vo) {
System.out.println("姓名:" + vo.getName() + " 年龄:" + vo.getAge() + " 身高:" + vo.getHeight());
}
//获得对象集合
private List<TestVo> getList(int num) {
List<TestVo> list = new ArrayList<>();
Random r = new Random();
for (int i = 0; i < num; i++) {
list.add(new TestVo(randomName(), r.nextInt(100), r.doubles(60, 200).findAny().getAsDouble()));
}
return list;
}
//获得一个对象
private TestVo getOne() {
Random r = new Random();
return new TestVo(randomName(), r.nextInt(100), r.doubles(60, 200).findAny().getAsDouble());
}
//随机生成一个名字
private String randomName() {
Random r = new Random();
int num = r.nextInt(4);
StringBuilder name = new StringBuilder();
for (int i = 0; i < num; i++) {
name.append(generateWord());
}
return name.toString();
}
//随机生成一个汉字
private String generateWord() {
char result = (char) (0x4e00 + (int) (Math.random() * (0x9fa5 - 0x4e00 + 1)));
return result + "";
}
二.常用函数式接口
1.判断真假 Predicate:test T->Boolean
List<TestVo> list = getList(10);
Predicate<Double> p = x -> x > 180;
list.forEach(i -> System.out.println(i.getName() + i.getHeight() + "身高大于180吗?" + p.test(i.getHeight())));
Predicate<TestVo> p2 = x -> x.getName().length() > 3;
list.forEach(i -> System.out.println(i.getName() + " 名字超过3个字吗" + p2.test(i)));
2.消费消息Consumer:accept T->void
Consumer<TestVo> consumer = ClassName::testPrint;
consumer.accept(getOne());
consumer.accept(getOne());
3.将T映射为R Function:apply T->R
//exp1
Function<Integer, TestVo> function = i -> new TestVo("1", i.intValue(), 123.0);
System.out.println(function.apply(12).getName());
//exp2
Function<TestVo, String> function1 = TestVo::getName;
System.out.println(function1.apply(getOne()));
4.生产消息 Supplier None->T
//ex1
Supplier<Integer> supplier1 = () -> Integer.parseInt("1");
//ex2
Supplier<TestVo> supplier = this::getOne;
System.out.println(supplier.get().getName());
5.一元操作 UnaryOperator T->T
//ex1
UnaryOperator<Boolean> unaryOperator = i -> !i;
Boolean apply2 = unaryOperator.apply(true);
System.out.println(apply2);
//ex2
UnaryOperator<TestVo> unaryOperator1 = i -> {
i.setName("嘿嘿嘿");
return i;
};
System.out.println(unaryOperator1.apply(getOne()));
6.二元操作 BinaryOperator(T,T)->T
//ex1
BinaryOperator<Integer> binaryOperator = (x, y) -> x * y;
System.out.println(binaryOperator.apply(3, 4));
//ex2
BinaryOperator<TestVo> binaryOperator1 = (x, y) -> new TestVo("老王", x.getAge() + y.getAge(), x.getHeight() + y.getHeight());
System.out.println(binaryOperator1.apply(getOne(), getOne()));
三.常用的流
1.collect(Collectors.toList())//还有toSet、toMap等 略
2.filter 内部就是Predicate接口 略
3.map 转换功能,内部是Function接口 略
4.flatMap 将多个Stream合并为一个Stream
List<TestVo> list = Stream.of(
getList(2), getList(3), getList(1)
).flatMap(Collection::stream).collect(Collectors.toList());
System.out.println("size:" + list.size());
5.max min 集合中最大最小
List<TestVo> list = getList(100);
Optional<TestVo> max = list.stream().max(Comparator.comparing(TestVo::getAge));
Optional<TestVo> min = list.stream().min(Comparator.comparing(TestVo::getAge));
max.ifPresent(testVo -> System.out.println("年龄最大的是:" + testVo.getName() + " 他的年龄是:" + testVo.getAge()));
min.ifPresent(testVo -> System.out.println("年龄最小的是:" + testVo.getName() + " 他的年龄是:" + testVo.getAge()));
6.count 统计功能,一般都是结合filter使用
List<TestVo> list = getList(100);
long count = list.stream().filter(i -> i.getAge() <= 45).count();
System.out.println("小于45岁的有:[" + count + "]人");
7.reduce 从一组值中生成一个值 (count 、 min 和 max 方法,因为常用而被纳入标准库中。事实上,这些方法都是 reduce 操作)
//exp1
List<Integer> integerList = Stream.of(1, 2, 3, 4).collect(Collectors.toList());
//Integer total = integerList.stream().reduce(0,(x,y)->x+y);
Integer total = integerList.stream().reduce(0, Integer::sum);
System.out.println(total);
//exp2
List<TestVo> list = getList(100);
Optional<TestVo> maxVo = list.stream().reduce((x, y) -> x.getAge() > y.getAge() ? x : y);
maxVo.ifPresent(testVo -> System.out.println("年龄最大的是:" + testVo.getName() + " 他的年龄是:" + testVo.getAge()));