温馨提醒:在电脑上看更方便
(一)stream的特点
一、 流操作都支持 lambda 表达式作为参数 ,函数式编程,充分利用了pipeline 思想
二、无修改 ,无储存
对原始数据无修改,对流和流的中间结果无储存
三 、 惰性执行
四、可以并发执行 , paralleStream
五、 默认只消费一次
1) 巧妙避免代码重复的方式 Supplier
-
Supplier<Stream<String>> streamSupplier = () -> Stream.of("1", "2").filter(t -> t.equals("1"));
-
final Optional<String> any = streamSupplier.get().findAny();//1
-
final Optional<String> first = streamSupplier.get().findFirst();//2
六、Map 不支持 stream 流
(二)函数接口简介
1)一元函数式接口
接口 | 参数 | 返回类型 | 描述 |
---|---|---|---|
Predicate | T | boolean | 断言型接口 |
Consumer | T | void | 消费型接口 |
Function | T | R | 函数式接口 |
Supplier | None | T | 供给型接口 |
2) 二元函数接口
接口 | 参数 | 返回类型 | 描述 |
---|---|---|---|
BiFunction | T, U | R | Function的变体 |
BiConsumer | T, U | void | Consumer的变体 |
BiPredicate | T, U | boolean | Predicate的变体 |
BiConsumer
-
final HashMap<Object, Object> objectObjectHashMap = Maps.newHashMap();
-
final BiConsumer biConsumer = (k, v) -> {
-
System.out.println(k);
-
System.out.println(v);
-
};
-
objectObjectHashMap.forEach(biConsumer);
BiPredicate
-
Path testPath = Paths.get("/Users/qiaozhy/data");
-
//finding files containing 'items' in name
-
final BiPredicate<Path, BasicFileAttributes> items = (path, basicFileAttributes) -> {
-
File file = path.toFile();
-
return !file.isDirectory() &&
-
file.getName().contains("items");
-
};
-
Stream<Path> stream =
-
Files.find(testPath, 100,items
-
);
-
stream.forEach(System.out::println);
3) 扩展的运算符
BinaryOperator 继承BiFunction
-
BinaryOperator<Integer> add = (n1, n2) -> n1 + n2;
UnaryOperator 继承Function
-
UnaryOperator<Integer> dda = x -> x + 1;
(三)stream的操作
一、 流的创建 (最终都是依赖底层的StreamSupport类来完成Stream创建)
1) Collection 和数组
Collection.stream()
Collection.parallelStream()
final Stream<String> stream = Arrays.asList("11", "22").stream();
final ArrayList<String> list = Lists.newArrayList();
list.add("33");
final Stream<String> stream3 = list.stream();
final Stream<String> stringStream2 = list.parallelStream();
2) BufferedReader
java.io.BufferedReader.lines()
File file = new File("/Users/qiaozhy/data/qiao.txt");
Reader reader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(reader);
final Stream<String> lines = bufferedReader.lines();
final long count = lines.count();
System.out.println(count);//2
3) 静态工厂
Arrays.stream(T array)
Stream.of()、iterate()、generate()
java.util.stream.IntStream.range()
java.nio.file.Files.list、find、walk等
Stream.builder()
-
final IntStream intStream1 = Arrays.stream(new int[]{1, 2, 3});
-
-
-
final Stream<String> stringStream = Stream.of("11", "22");
-
-
final Stream<Integer> iterate = Stream.iterate(5, t -> t + 1);
-
iterate.limit(4).forEach(System.out::println);//5,6,7,8
-
-
//supplier 函数式接口的简化 (Math::random)
-
Stream.generate(Math::random).limit(1).forEach(System.out::println);
-
// 0.48158792725573907
-
-
final IntStream intStream = IntStream.range(1, 3);
-
-
-
final Optional<Path> first = Files.walk(Paths.get("/Users/qiaozhy/data"))
-
.peek(System.out::println).skip(2).findAny();
-
first.orElseThrow(()-> new RuntimeException("结果为空"));
-
System.out.println(first.get());//Users/qiaozhy/data/工作注意.txt
-
-
final Stream.Builder<Object> builder1 = Stream.builder();
-
builder1.accept(66);
-
builder1.add(2).add(3);
-
builder1.build().forEach(System.out::println); // 66,2,3
4)其他
Pattern.splitAsStream(java.lang.CharSequence)
Random.ints()
JarFile.stream()
BitSet.stream()
-
final Pattern pattern = Pattern.compile(",");
-
final Stream<String> stringStream1 = pattern.splitAsStream("a,y,u");
-
stringStream1.forEach(System.out::println);// a,y,u
-
-
Random random = new Random();
-
final IntStream intStream2 = random.ints(1,20);
-
intStream2.limit(2).forEach(System.out::println); // 5,18
-
-
JarFile jarFile = new JarFile("/Users/qiaozhy/.m2/javacc-5.0.jar");
-
final Stream<JarEntry> stream1 = jarFile.stream();
-
stream1.limit(1).forEach(System.out::println); //META-INF/
-
-
BitSet bitSet = new BitSet();
-
bitSet.set(1);
-
bitSet.set(45);
-
final IntStream stream2 = bitSet.stream();
-
stream2.forEach(System.out::println); // 1,45
二、 中间操作
无状态(Stateless)操作:每个数据的处理是独立的,不会影响或依赖之前的数据。如
filter()
、 flatMap()
、 flatMapToDouble()
、 flatMapToInt()
、 flatMapToLong()
、 map()
、 mapToDouble()
、 mapToInt()
、 mapToLong()
、 peek()
、 unordered()
等
unordered操作不会进行任何显式的打乱流的操作。它的工作是:消除流中必须保持的有序约束,因此允许之后的操作使用 不必考虑有序的优化
有状态(Stateful)操作:处理时会记录状态,比如处理了几个。后面元素的处理会依赖前面记录的状态,或者拿到所有元素才能继续下去。如
distinct()
、 sorted()
、 sorted(comparator)
、 limit()
、 skip()
等
-
String [] arr = {"a","b","ed","c"};
-
final List<String> collect = Arrays.stream(arr).sorted(Comparator.comparing(String::length)).collect(Collectors.toList());
-
System.out.println(collect);//[a, b, c, ed]
-
final List<String> collect1 = Arrays.stream(arr).sorted(Comparator.reverseOrder()).collect(Collectors.toList());
-
System.out.println(collect1);//[ed, c, b, a]
-
final Optional<String> any = Arrays.stream(arr).distinct().skip(1).limit(1).findAny();
-
any.orElseThrow(()-> new RuntimeException("结果为空"));
-
final String s = any.get();
-
System.out.println(s);//b
-
String[] words = new String[]{"Hello","World"};
-
Arrays.stream(words)
-
.map(word -> word.split(""))
-
.flatMap(Arrays::stream)
-
.forEach(System.out::print);
-
//HelloWorld
-
List<String> first= Arrays.asList("one", "two", "three", "four");
-
List<String> second= Arrays.asList("A", "B", "C", "D");
-
Stream.of(first,second).flatMap(Collection::stream).forEach(System.out::print);//onetwothreefourABCD
-
Stream.of(1.0,2.0,3.0).mapToInt(Double::intValue).mapToObj(i->"a"+i).forEach(System.out::print);
三、终止操作
非短路操作:处理完所有数据才能得到结果。如
collect()
、 count()
、 forEach()
、 forEachOrdered()
、 max()
、 min()
、 reduce()
、 toArray()
等。
短路(short-circuiting)操作:拿到符合预期的结果就会停下来,不一定会处理完所有数据。如
anyMatch()
、 allMatch()
、 noneMatch()
、 findFirst()
、 findAny()
等
-
List<String> strs = Arrays.asList("a", "a", "a", "a", "b");
-
boolean aa = strs.stream().anyMatch(str -> str.equals("a"));
-
System.out.println(aa);//true
-
boolean bb = strs.stream().allMatch(str -> str.equals("a"));
-
System.out.println(bb);//false
-
boolean cc = strs.stream().noneMatch(str -> str.equals("a"));
-
System.out.println(cc);//false
-
String [] arr = {"a","b","ed","c"};
-
final Optional<String> reduce = Arrays.stream(arr).reduce((a, b) -> a + b);
-
reduce.orElseThrow(()-> new RuntimeException("结果为空"));
-
System.out.println(reduce.get());//abedc
-
-
List<Integer> numList = Arrays.asList(1,2,3,4,5);
-
int result = numList.stream().reduce(0,(a,b) -> a + b );
-
System.out.println(result);
-
-
List<Integer> numList1 = Arrays.asList(1, 2, 3, 4, 5, 6);
-
ArrayList<String> result1 = numList1.stream().reduce(new ArrayList<String>(),
-
(a, b) -> {
-
a.add("element-" + Integer.toString(b));
-
return a;
-
}, (a, b) -> null);
-
System.out.println(result1);
-
/*
-
需要注意的是这个reduce的签名还包含第三个参数,一个BinaryOperator<U>类型的表达式。
-
在常规情况下我们可以忽略这个参数,敷衍了事的随便指定一个表达式即可,目的是为了通过编译器的检查,
-
因为在常规的stream中它并不会被执行到,然而, 虽然此表达式形同虚设,可是我们也不是把它设置为null,
-
否者还是会报错。 在并行stream中,此表达式则会被执行到,在这里我们不进行讲解,因为我自己也没用过
-
*/
-
Supplier<Stream<String>> streamSupplier = () -> Stream.of("a","d","b");
-
//输出的顺序与元素的顺序严格一致
-
streamSupplier.get().parallel().forEachOrdered(System.out::println);//a,d,b
-
//主要的区别在并行流的处理上
-
//输出的顺序不一定(效率更高)
-
streamSupplier.get().parallel().forEach(System.out::println); // d,a,b
-
-
final String[] strings = streamSupplier.get().toArray(String[]::new);
-
System.out.println(Arrays.toString(strings));//[a, d, b]
-
final ArrayList<String> list = Lists.newArrayList();
-
list.add("12");
-
list.add("111");
-
final List<String> collect = list.stream().collect(Collectors.toList());
-
final Set<String> collect1 = list.stream().collect(Collectors.toSet());
-
final Map<Integer, String> collect2 = list.stream().collect(Collectors.toMap(String::length, String::valueOf));
-
-
final Long lo = list.stream().collect(Collectors.counting());
-
-
final IntSummaryStatistics intSummaryStatistics = list.stream().collect(Collectors.summarizingInt(Integer::valueOf));
-
-
final String collect3 = list.stream().collect(Collectors.joining("--"));
-
-
final Optional<String> collect4 = list.stream().collect(Collectors.reducing((x, y) -> x + y));
-
-
final Map<Integer, List<String>> collect5 = list.stream().collect(Collectors.groupingBy(String::length));
-
-
final Optional<Integer> collect6 = list.stream().map(Integer::valueOf).collect(Collectors.maxBy(Integer::max));
(四 )、并行流
在创建Stream时,默认是创建串行流。但是可以使用parallelStream()来创建并行流或者parallel()将串行流转换成并行流。并行流也可以通过sequential()转换成串行流。
Java 8 Stream的并行流,本质上还是使用Fork/Join模型
(五)、特殊用法
-
// map的循环方式
-
final HashMap<Object, Object> objectObjectHashMap = Maps.newHashMap();
-
objectObjectHashMap.put("1","2");
-
objectObjectHashMap.put("5","77");
-
objectObjectHashMap.forEach((a,b)->{
-
System.out.println(a);
-
System.out.println(b);
-
});