jdk8特性例子 流 Streams

2/22/2017来源:ASP.NET技巧人气:1790

java.util.Stream rePResents a sequence of elements on which one or more Operations can be performed. Stream operations are either intermediate or terminal. While terminal operations return a result of a certain type, intermediate operations return the stream itself so you can chain multiple method calls in a row. Streams are created on a source, e.g. a java.util.Collection like lists or sets (maps are not supported). Stream operations can either be executed sequential or parallel.

       stream 表示一个序列,在这个序列上可以执行一个或多个操作。流操作分为中间操作和最终操作两类,最终操作返回一个特定类型的结果,中间结果返回流对象,这样可以在同一行链式调用多个方法。创建stream要指定数据源,collection 例如list 、set(不支持map)。stream操作可以串行、也可以并行。

List<String> stringCollection = new ArrayList<>();
stringCollection.add("ddd2");
stringCollection.add("aaa2");
stringCollection.add("bbb1");
stringCollection.add("aaa1");
stringCollection.add("bbb3");
stringCollection.add("ccc");
stringCollection.add("bbb2");
stringCollection.add("ddd1");      stream 可以通过Collection.stream() or Collection.parallelStream()  创建。

Filter

   Filter accepts a predicate to filter all elements of the stream. This operation is intermediatewhich enables us to call another stream operation (forEach) on the result. ForEach accepts a consumer to be executed for each element in the filtered stream. ForEach is a terminal operation. It's void, so we cannot call another stream operation.

     Filter 接受一个谓词过滤stream里的所有元素。filter是中间操作,其结果可以调用另一个操作。forEach 接受一个函数【函数式接口Consumer】,操作流对象里的每一个元素。forEach是最终操作。不能再调用另一个流操作。

     

		// aaa2 aaa1
		stringCollection.stream().filter((s) -> s.startsWith("a")).forEach(System.out::println);

Sorted

Sorted is an intermediate operation which returns a sorted view of the stream. The elements are sorted in natural order unless you pass a custom Comparator.       sorted 是中间操作,返回stream排序后的视图。流元素自然顺序排序,除非指定一个Comparator。
		// "aaa1", "aaa2"
		stringCollection.stream().sorted().filter((s) -> s.startsWith("a")).forEach(System.out::println);Keep in mind that sorted does
 only create a sorted view of the stream without manipulating the ordering of the backed collection. The ordering of stringCollection is
 untouched:
       注意 sorted只是创建一个流的排序视图,而不会修改原来集合的顺序。原来对象stringCollection 不会被修改。
		// ddd2, aaa2, bbb1, aaa1, bbb3, ccc, bbb2, ddd1
		System.out.println(stringCollection);

Map

The intermediate operation map converts each element into another object via the given function. The following example converts each string into an upper-cased string. But you can also use map to transform each object into another type. The generic type of the resulting stream depends on the generic type of the function you pass to map.

     map是一个中间操作,它把每个元素通过指定的方法转换成另一个对象。下面的例子吧string转换成大写的string,也可以把对象转换成其他类型。结果流的类型依赖传入给map的函数的执行结果的类型。
		// "DDD2", "DDD1", "CCC", "BBB3", "BBB2", "AAA2", "AAA1"
		stringCollection.stream().map(String::toUpperCase).sorted((a, b) -> b.compareTo(a))
				.forEach(System.out::println);

Match

Various matching operations can be used to check whether a certain predicate matches the stream. All of those operations are terminal and return a boolean result.

          提供各种match匹配操作,用于检查指定的predicate是否匹配整个stream。所有的这些匹配操作是最终操作,返回boolean结果。
		boolean anyStartsWithA = stringCollection.stream().anyMatch((s) -> s.startsWith("a"));
		System.out.println(anyStartsWithA); // true

		boolean allStartsWithA = stringCollection.stream().allMatch((s) -> s.startsWith("a"));
		System.out.println(allStartsWithA); // false

		boolean noneStartsWithZ = stringCollection.stream().noneMatch((s) -> s.startsWith("z"));
		System.out.println(noneStartsWithZ); // true

Count

Count is a terminal operation returning the number of elements in the stream as a long.

     count是一个最终操作,返回stream中的元素个数,返回值是long类型。

		long startsWithB = stringCollection.stream().filter((s) -> s.startsWith("b")).count();
		System.out.println(startsWithB); // 3

Reduce 简化|规约 翻译都不好

This terminal operation performs a reduction on the elements of the stream with the given function. The result is an Optional holding the reduced value.

 reduce操作是对流上的元素根据指定的函数执行reduction操作。结果是Optional,保存简化后的结果。

		Optional<String> reduced = stringCollection.stream().sorted().reduce((s1, s2) -> s1 + "#" + s2);
		// "aaa1#aaa2#bbb1#bbb2#bbb3#ccc#ddd1#ddd2"
		reduced.ifPresent(System.out::println);
ParallelStream

As mentioned above streams can be either sequential or parallel. Operations on sequential streams are performed on a single thread while operations on parallel streams are performed concurrent on multiple threads.

    stream可以是串行也可以是并行的。串行stream单线程执行的,并行stream是多线程并行执行的。

public class ParallelStreamTest {
	public static void main(String[] args) {
		int max = 1000000;
		List<String> values = new ArrayList<>(max);
		for (int i = 0; i < max; i++) {
			UUID uuid = UUID.randomUUID();
			values.add(uuid.toString());
		}
		long t0 = System.nanoTime();

		long count = values.stream().sorted().count();
		System.out.println(count);

		long t1 = System.nanoTime();

		long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);

		System.out.println(String.format("sequential sort took: %d ms", millis));
		long t2 = System.nanoTime();

		long count2 = values.parallelStream().sorted().count();
		System.out.println(count2);

		long t3 = System.nanoTime();

		long millis2 = TimeUnit.NANOSECONDS.toMillis(t3 - t2);
		System.out.println(String.format("parallel sort took: %d ms", millis2));
	}
}
结果大概差 50%。

1000000
sequential sort took: 1271 ms
1000000
parallel sort took: 560 ms