Java Stream API

Java Streams

Java在JDK1.8中引入了Stream API,支持对流的处理。流处理类似于对于数据库数据流进行只读操作后求得某种结果,有如下特点:

Java-Streams

  1. stream不存储数据
  2. stream不改变源数据
  3. stream的延迟执行特性

Stream API 简述

创建Stream

Stream.of(Collection collections)时Stream类的静态方法,可以将集合数据转化为Stream。

1
2
3
4
5
//Stream.of()
Stream<Student> stream = Stream.of(stuArr);
//Arrays.stream
int[] arr = new int[]{1,2,34,5};
IntStream intStream = Arrays.stream(arr);

Stream操作

Reference Link: https://www.cnblogs.com/CarpenterLee/p/6545321.html

操作类型 接口方法
中间操作 concat() distinct() filter() flatMap() limit() map() peek() skip() sorted() parallel() sequential() unordered()
结束操作 allMatch() anyMatch() collect() count() findAny() findFirst() forEach() forEachOrdered() max() min() noneMatch() reduce() toArray()

对于接口方法的传入参数,是各种函数接口,可以用lamda表达式方便的书写。下面介绍几个经典的API使用:

  1. forEach()

forEach(Consumer<? super E> action)

1
2
3
// 使用Stream.forEach()迭代
Stream<String> stream = Stream.of("I", "love", "you", "too");
stream.forEach(str -> System.out.println(str));
  1. filter()

filter(Predicate<? super E> predicate)

1
2
3
4
// 保留长度等于3的字符串
Stream<String> stream= Stream.of("I", "love", "you", "too");
stream.filter(str -> str.length()==3)
.forEach(str -> System.out.println(str));
  1. map()

Stream map(Function<? super T,? extends R> mapper)

1
2
3
Stream<String> stream = Stream.of("I", "love", "you", "too");
stream.map(str -> str.toUpperCase())
.forEach(str -> System.out.println(str));
  1. reduce()

reference Link: http://www.cnblogs.com/CarpenterLee/p/6550212.html

  • Optional reduce(BinaryOperator accumulator)
  • T reduce(T identity, BinaryOperator accumulator)
  • <U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
1
2
3
4
5
6
// 找出最长的单词

Stream<String> stream = Stream.of("I", "love", "you", "too");
Optional<String> longest = stream.reduce((s1, s2) -> s1.length()>=s2.length() ? s1 : s2);
//Optional<String> longest = stream.max((s1, s2) -> s1.length()-s2.length());
System.out.println(longest.get());
  1. collect()
  • R collect(Supplier supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner)
  • <R,A> R collect(Collector<? super T,A,R> collector)
1
2
3
4
5
// 将Stream规约成List
Stream<String> stream = Stream.of("I", "love", "you", "too");
List<String> list = stream.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);// 方式1
//List<String> list = stream.collect(Collectors.toList());// 方式2
System.out.println(list);

LINQ in C#

与Java语言相比,C#引入了LINQ,lamda表达式和扩展方法来更好的支持chaining operation。LinQ支持所有实现了Enumberable接口的类型。

  1. ForEach()

    .ForEach(Action action)

1
2
3
4
5
6
List<string> stringList = new List<string>();
stringList.Add("I");
stringList.Add("love");
stringList.Add("you");
stringList.Add("too");
stringList.ForEach(a => Console.WriteLine(a));
  1. Where()

    .Where(Func<T, bool> function)

1
2
stringList.Where( x=> x.Length == 3)
.ForEach( x=> Console.WriteLine(x));
  1. Select()

    .Select(Func<T, int, R> function)

1
2
stringList.Selct((x, i) => x.ToUpper())
.ForEach( x=> Console.WriteLine(x));
  1. Aggregate()

    .Aggregate(A, Func<A, T, A> function, Func<A, R> function2)

1
stringList.Aggregate("", (cur, next) => cur.Length > next.Length ? cur : next, x => Console.WriteLine(x));
  1. 扩展方法,Java collect()方法是.NET扩展方法功能的一种实现,C#通过定义扩展方法更好的支持LINQ的Chaining功能,使得Java Collectors的接口都可以直接通过相似的方法实现。
1
stringList.Select(x=>x).toList();