Java8 随笔记录(三)

关于流的使用,Stream API提供了很多的操作

1、常用操作

stream.filter(vo -> vo.getAge()>25).distinct().skip(3).limit(6)
.collect(Collectors.toList());

// distinct 去重,排除重复元素
// skip 跳过,即扔掉前n个元素
// limit 截断流,返回n个元素,与skip组合可作为内存上的分页

2、map + flatMap 之间的联系:

// 直接使用map打印: i: 1i: 3i: 5
// 使用flatMap打印:
// i: 1j: 7
// j: 8
// i: 3j: 7
// j: 8
// i: 5j: 7
// j: 8
List<Integer> one = Lists.newArrayList(1, 3, 5);
List<Integer> two = Lists.newArrayList(7, 8);
one.stream().flatMap(i -> {
     System.out.print("i: " + i + "\t");
 
     return two.stream().map(j -> {
           System.out.println("j: " + j);
           return new int[]{i, j};
     });
}).count();

当使用map时,鼠标移到map上去看会显示:

<Stream<Object>> Stream<Stream<Object>> java.util.stream.Stream.map(Function<? super Integer, ? extends Stream<Object>> mapper)

而当使用flatMap时,会显示:

<Object> Stream<Object> java.util.stream.Stream.flatMap(Function<? super Integer, ? extends Stream<? extends Object>> mapper)

也就是说,flatMap是先map然后再flat,这一点和spark中的map/flatMap类似。

其次,看别人博客里有介绍,flatMap方法会让你把流中的每一个值都转换成另一个流,然后把所有流连接起来成为一个流。

 

3、查找和匹配

对于这一点,Stream API提供的有allMatch、anyMatch、noneMatch、findFirst、findAny这些函数。

allMatch,当所有元素都匹配条件时才为真。
anyMatch,也就是只要有一个元素匹配就为真了。
noneMatch,和allMatch相反,即所有元素都不匹配时才为真。
findFirst,返回第一个元素,当多线程的时候可能会出现问题,所以当不是特意指定返回第一个元素时,
可以使用findAny来处理会更好一些。
findAny,返回当前流中的任意元素,当没有满足条件的元素时,避免返回null,java8新增了一个
Optional<T>类来避免空指针。

 

4、Optional的常规操作:

// 当Optional中存在值的时候返回true,否则返回false。
isPresent()
// 当Optional中存在值的时候才会执行Consumer块,否则不执行。
ifPresent(Consumer<T> block)
// 当Optional中存在值的时候返回值,否则抛NoSuchElementException异常。
T get()
// 当Optional中存在值的时候返回值,否则返回默认值。
T orElse(T other)
-------------------------------------
// 返回一个空的Optional实例
Optional<T> empty() 
// 将指定值用Optional封装之后再返回,如果value为null,则抛出异常
Optional<T> of(T value) 
// 将指定值用Optional封装之后再返回,如果value为null,则返回空的Optional对象
Optional<T> ofNullable(T value)
// 如果值存在并且满足Predicate条件,就返回该对象,否则返回一个空的Optional对象
Optional<T> filter(Predicate<? super T> predicate)
// 如果值存在,就对该值执行Function
Optional<U> map(Function<? super T, ? extends U> mapper)
// 如果值存在,就对该值执行Function,否则返回空的Optional对象
Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
// 如果有值就返回,否则返回由Supplier生成的值
T orElseGet(Supplier<? extends T> other)
// 如果有值就返回,否则返回由Supplier生成的异常
T orElseThrow(Supplier<? extends X> exceptionSupplier)
// 判断对象相等
boolean equals(Object obj)
具体的使用效果可以自己去实践操作下。

 

5、reduce的相关规约:

求和:
System.out.println(Lists.newArrayList(1,2,3,4,5).parallelStream()
.reduce(0, Integer::sum)); //15
System.out.println(Lists.newArrayList(1,2,3,4,5).parallelStream()
.mapToInt(s -> s).max()); //15,先将其转成java.util.stream.IntStream原始类型流
最大值:
System.out.println(Lists.newArrayList(1,2,3,4,5).stream()
.reduce(0, Integer::max)); //5
System.out.println(Lists.newArrayList(1,2,3,4,5).stream()
.mapToInt(s -> s).max()); //5
最小值:
System.out.println(Lists.newArrayList(1,2,3,4,5).stream()
.reduce(0, Integer::min)); //此处并不是1,而是默认值0
System.out.println(Lists.newArrayList(1,2,3,4,5).stream()
.mapToInt(s -> s).min()); //0
平均数:
System.out.println(Lists.newArrayList(1,2,3,4,5).stream()
.mapToInt(s -> s).average()); //OptionalDouble[3.0],
此处之所以返回类型是OptionalDouble而不直接是double,是因为流中可能没有值,
而为了避免null空指针,就采用了Optional模式。
通过mapToInt、mapToLong、mapToDouble返回的都是原始类型流,当然也可以回转成对象流,
只需要直接intStream.boxed()即可。

 

6、创建流

还是延用以前的一个例子:

// Stream.of 方式创建流
List<String> list = Stream.of("one", "two", "three", "four")
            .filter(e -> e.length() > 3)
            .peek(e -> System.out.println("Filtered value: " + e))
            .map(String::toUpperCase)
            .peek(e -> System.out.println("Mapped value: " + e))
            .collect(Collectors.toList());
// peek 可以在流的执行过程中保持流状态不变的情况下执行别的操作,可做日志打印
// Filtered value: three
// Mapped value: THREEfc
// Filtered value: four
// Mapped value: FOUR
 
// 创建一个[1, 10]区间大小的流
IntStream.rangeClosed(1, 10); 
 
// 用数组来创建流
Arrays.stream(new String[]{"wsbs","xwzx","bmfw","wshd"});
 
// 用文件生成流
Files.lines(Paths.get(new URI("/Users/Max/Documents/java8.pages")));
 
// 使用iterate来迭代生成一个无限流,此处使用limit进行了截断
Stream.iterate(0, n -> ++n).limit(6);
 
// 使用generate来生成一个无限流, 打印2个6
 
Stream.generate(() -> 6).limit(2).forEach(System.out::println); 

 

猜你喜欢

转载自study121007.iteye.com/blog/2298133