@Test public void test24(){ //去掉所有的重复数字 且 只留偶数 //中间加工处理绝不仅仅只能写一步,它可以写很多步 Stream.of(1,2,3,4,5,2,4,6,5,3,1) //创建流 .distinct() //中间加工处理 .filter(t-> t%2==0) //中间加工处理 .forEach(t-> System.out.print(t+"\t")); //终结操作 }
@Test public void test25(){ //在初始元素为1,元素累加2的无限流中,取前10个 Stream.iterate(1,t->t+2) .limit(10)//取无限流中前10个 .forEach(System.out::println); }
@Test public void test26(){ //在初始元素为1,元素累加2的无限流中,跳过前10个,并只取前10个 Stream.iterate(1,t->t+2) .skip(10)//跳过无限流中前10个 .peek(t->{ //数据每隔200ms出现一次,使之不要出现的那么的快 try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } }) .limit(10) //只取前10个 .forEach(System.out::println); }
@Test public void test27(){ //统计这组数据中的偶数个数,是不重复的偶数,并且要打印出来 long count=Stream.of(1,2,3,4,5,2,4,6,5,3,1) //创建流 .filter(t -> t%2==0) // 过滤偶数 中间加工处理 .distinct() //去重复 .peek(t-> System.out.print(t+"\t")) //中间加工 .count(); System.out.println(); System.out.println("偶数个数:"+count); }
@Test public void test28(){ //从小到大排序 Stream.of(1,5,2,89,45,32,9,12) //创建流 .sorted() //中间加工 排序 .forEach(System.out::println); //终结 }
@Test public void test29(){ ArrayList<Student> list=new ArrayList<>(); list.add(new Student("kfc")); list.add(new Student("dragon")); //按照名字排序 list.stream() //创建流 .sorted((s1,s2)-> s1.getName().compareTo(s2.getName()))//中间加工 排序 .forEach(t -> System.out.println(t)); //终结 }
@Test public void test30(){ //将原来流中的数据变成它的2倍并打印 Stream.of(1,2,3,4,5)//创建流 .map(t-> t*2) //中间加工 .forEach(System.out::println); //终结 }
@Test public void test31(){ //取出单词的首字目 Stream.of("hello","world","java") .map(t -> t.charAt(0) ) .forEach(System.out::println); }
@Test public void test32(){ //把字符串每个字符串起来,变成一个新的流 /* <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper); Function<TR>是功能型函数式接口 抽象方法 R apply(T t) T: ? super T R : ? extends Stream?extends R> 说明function函数使用后,apply方法结果要是一个stream对象 <R> Stream<R> map(Function<? super T, ? extends R> mapper); T: ? super T R: ? extends R */ Stream.of("hello","world","java") .flatMap( t-> { char[] chars = t.toCharArray(); Character[] c = new Character[chars.length]; for (int i = 0; i < chars.length; i++) { c[i] = chars[i]; } return Arrays.stream(c); }) .forEach(System.out::println); }
(3) 终结操作,它的方法的返回值不再是一个流,而是其他的类型
注意:
中间加工处理的方法返回值结果仍然是stream类型。
终结操作处理的方法返回值结果就不再是stream类型。表示之后无法再进行流处理。
具体的方法:
| 方法 | 描述 |
| booleanallMatch(Predicate p) | 检查是否匹配所有元素 |
| booleananyMatch(Predicate p) | 检查是否至少匹配一个元素 |
| booleannoneMatch(Predicate p) | 检查是否没有匹配所有元素 |
| OptionalfindFirst() | 返回第一个元素 |
| OptionalfindAny() | 返回当前流中的任意元素 |
| longcount() | 返回流中元素总数 |
| Optionalmax(Comparator c) | 返回流中最大值 |
| Optionalmin(Comparator c) | 返回流中最小值 |
| voidforEach(Consumer c) | 迭代 |
| Treduce(T iden, BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值。返回 T |
| Ureduce(BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值。返回 Optional |
| Rcollect(Collector c) | 将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法 |
代码演示如下:
@Test public void test33(){ //判断是否全部为奇数 boolean b= Stream.of(1,2,3,4,5,2,4,6,5,3,1)//创建流 .allMatch(t -> t%2!=0); //终结 System.out.println("是否全部为奇数:"+b); }
@Test public void test34(){ Optional<Integer> first = Stream.of(1, 2, 3, 4, 5, 2, 4, 6, 5, 3, 1)//创建流 .findFirst(); //终结 System.out.println("第一个:"+first); } @Test public void test35(){ //对于稳定的流(元素稳定且固定),findAny() 等价于 findFirst() Optional<Integer> any = Stream.of(1, 2, 3, 4, 5, 2, 4, 6, 5, 3, 1)//创建流 .findAny(); //终结 System.out.println("第一个:"+any); }
@Test public void test36(){ //随机产生10个【0-100】的整数,找出最大值 Optional<Integer> max= Stream.generate(() -> (new Random().nextInt(101))) .limit(10) .peek(t-> System.out.print(t+"\t")) .max(Integer::compareTo); System.out.println(max); }
@Test public void test37(){ //累加和 /* Optional<T> reduce(BinaryOperator<T> accumulator); public interface BinaryOperator<T> extends BiFunction<T,T,T> public interface BiFunction<T,U,R> 的抽象方法 R apply(T t,U u); BinaryOperator接口的抽象方法 T apply(T t,T u); */ Optional<Integer> reduce = Stream.of(1, 2, 3, 4, 5) .reduce((t1, t2) -> t1 + t2); System.out.println(reduce); }
@Test public void test38(){ /* ColLector 接口中方法的实现决定了如何对流执行收集的操作(如收集到 List、Set、Map)。 另外, CoLLectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例。*/ ArrayList<String> list=new ArrayList<>(); list.add("jack"); list.add("hello"); list.add("world"); list.add("java"); Set<String> a = list.stream() .filter(s -> s.contains("a")) .peek(s -> System.out.println(s)) .collect(Collectors.toSet()); System.out.println("list:"+list); System.out.println("set:"+a); }
十二.Optional 类
12.1 为什么要引入Optional类?
原因:
Java很多方法的返回值 (更多是返回值)
或形参是引用数据类型时,返回null。对方拿到这个数据时,没有做非空判断的话,会发生空指针异常。或者说是加非空判断f (xx !=
null)使得代码很臃肿。
引入了optional类来尽量的降低空指针异常的风险,又可以简化代码。
12.2 Optional类特点
(1) 它是一个容器
(2) 只包含一个对象的容器
12.3 如何使用它?
12.3.1 创建它
static Optional empty(): 得到一个空的容器对象,里面没有元素,容器对象有。staticOptionalof(T value) : 得到一个包含元素的容器对象,里面一定有元素,而且非null
代码演示如下:
@Test public void test01(){ Optional<Object> empty = Optional.empty(); System.out.println(empty); Optional<String> java = Optional.of("java"); System.out.println(java); Optional<Object> o = Optional.of(null); System.out.println(o); }
static Optional ofNullable(T value) : 得到一个包含元素的容器对象,里面一定有元素,元素可以是非null。可以是null
代码演示如下:
@Test public void test02(){ String str=null; Optional<String> str1 = Optional.ofNullable(str);//允许为null System.out.println(str1); }
12.3.2 取出容器中的数据
T get(): 要求容器中必须有一个非空对象
T orELse(T other) : 如果容器中有非空对象,就取容器中非空对象,如果没有,就用other备胎。
代码演示如下:
@Test public void test03(){ Optional<Integer> maxOptional = Stream.of(1, 3, 5, 7, 9) .filter(t -> t % 2 == 0) .max(Integer::compareTo); // Integer integer = maxOptional.get();//java.util.NoSuchElementException: No value present maxOptional里值为空 Integer max = maxOptional.orElse(0); System.out.println(max); }
T orELseget(Supplier<? extends T>other): 如果容器中有非空对象,就取容器中非空对象,如果没有,就用Supplier接口提供的对象代替
代码演示如下:
@Test public void test04(){ Random random=new Random(); Optional<Integer> maxOptional = Stream.of(1, 3, 5, 7, 9) .filter(t -> t % 2 == 0) .max(Integer::compareTo); // Integer integer = maxOptional.get();//java.util.NoSuchElementException: No value present maxOptional里值为空 Integer max = maxOptional.orElseGet(() -> random.nextInt(100)); //若无偶数,则返回一个100以内的随机整数 System.out.println(max); }
T orElseThrow(Supplier<? extends X> exceptionSupplier) :
如果Optional容器中非空,就返回所包装值,如果为空,就抛出你指定的异常类型代替原来的NoSuchElementException
代码演示如下:
@Test public void test05(){ Random random=new Random(); Optional<Integer> maxOptional = Stream.of(1, 3, 5, 7, 9) .filter(t -> t % 2 == 0) .max(Integer::compareTo); // Integer integer = maxOptional.get();//java.util.NoSuchElementException: No value present maxOptional里值为空 Integer max = maxOptional.orElseThrow(() -> new RuntimeException("没有最大值")); //没有偶数,就抛出里面的异常 System.out.println(max); }
12.3.3 其他
boolean isPresent() : 判断容器中有没有元素
void ifPresent(Consumer<? super T> consumer) : 如果存在就执行xx代码
代码演示如下:
@Test public void test06(){ Optional<Integer> maxOptional = Stream.of(1, 3, 5, 7, 9) .filter(t -> t % 2 == 0) .max(Integer::compareTo); // Integer integer = maxOptional.get();//java.util.NoSuchElementException: No value present maxOptional里值为空 maxOptional.ifPresent(s -> System.out.println(s)); //若有最大的偶数,就打印,没有就什么都不打印 }



















