It's been 4 months since I changed jobs to an engineer with no experience and was assigned to the java team. I'm already used to java, but I'm using the extended for statement to expand list. I want to get along with Stream API, so I summarized it.
We plan to add methods as needed.
As a starting point, I think it's good to have an impression of "** something that allows you to easily operate the array **". Lazy evaluation and asynchronous processing are described below, but you do not need to know at first. (I don't understand much, so I want to think so ..)
Stream can operate arrays with a small amount of description, and has the following functions.
Stream API can perform the asynchronous processing. Asynchronous processing, as the name implies, is not executing a series of processing sequentially (synchronizing), but performing it in parallel (asynchronous). When performing asynchronous processing with StreamAPI, use list.parallelStream () or List.stream (). Parallel () instead of the usual List.stream ().
For example, if there is a process to output the following list elements to the screen,
List<Integer> demoList = Arrays.asList(1, 2, 3, 4, 5);
If done synchronously, the output will be in the order of the array as it will be executed sequentially.
for(Integer i : demoList) {
System.out.print(i);
}
// 12345
However, if you do it asynchronously, it will be processed in parallel, so the output will be different from the array order.
demoList.stream().parallel().forEach(System.out::print);
// 32415
Also, by performing asynchronous processing, it is possible to process faster than turning the list with For. I actually measured the time.
//Target List
List<Integer> demoList = Stream.iterate(1, n -> n + 1).limit(100000).collect(Collectors.toList());
//For Get the time before processing
long startTimeFor = System.currentTimeMillis();
//Output with For
for(Integer i : demoList) {
System.out.println(i);;
}
//Get the time after For processing
long endTimeFor = System.currentTimeMillis();
//Get the time before Stream processing
long startTimeStream = System.currentTimeMillis();
//Output with Stream
demoList.parallelStream().forEach(System.out::println);
//Get the time after Stream processing
long endTimeStream = System.currentTimeMillis();
System.out.println("Processing time For:" + (endTimeFor - startTimeFor) + " ms");
System.out.println("Processing time Stream:" + (endTimeStream - startTimeStream) + " ms");
The results are as follows. The difference is not as great as I expected, but the above process was about 100ms faster on average.
Processing time For: 686 ms
Processing time Stream: 573 ms
The Stream API allows lazy evaluation of functional languages. What is lazy evaluation?
In programming, formulas are often calculated when they appear, but lazy evaluation is the process of not calculating them until they are actually needed.
It is. In StreamAPI, expressions are not evaluated during intermediate operations (map and filter) described later. It is evaluated only when the termination operation is performed. Let's actually move it and verify it.
//Target List
List<Integer> demoList = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
//Streaming only even numbers Since it is an intermediate process, it has not been evaluated yet.
Stream<Integer> oddListStream = demoList.stream().filter(n -> n % 2 == 0);
//Add element to demoList
demoList.add(6);
demoList.add(7);
demoList.add(8);
//Output Stream
oddListStream.forEach(System.out::print);
If you think about it normally, the oddListStream that is generating the Stream should contain 2 and 4. However, Stream's intermediate operations are lazy and will not be evaluated until the termination operation forEach is called. So the output is ...
$ 2468
And, 6,7,8 added to demoList after Stream generation is processed.
From here, we will actually look at the Stream operation in the order of generation → intermediate operation → termination operation.
First, create a Stream that is the basis for performing the operations described below. In addition to the commonly used List.stream (), Stream has various methods such as using a constructor and using a builder.
//From list type
Stream<Integer> numberStreamFromList = Arrays.asList(8, 1, 4, 2, 9).stream();
// Stream.with of
Stream<Integer> numberStreamFromStreamOf = Stream.of(8, 1, 4, 2, 9);
//Using builder
Builder<String> builder = Stream.builder();
Stream<String> stringStream = builder.add("hoge").add("fuga").build();
//Empty Stream
Stream<String> emptyStream = Stream.empty();
//With iterate
Stream<Integer> numberStreamFromIterate = Stream.iterate(1, n -> n * 10).limit(5);
Only the method of using iterate is a little difficult to understand, so it is a supplement. The basic syntax is as follows.
Stream.iterate(initial value, initial valueが入る変数 ->Processing for variables).limit(Number of repetitions)
The reason why limit is applied is that if limit is not used, it will be generated infinitely.
You can easily do this output with iterate.
Say a number from 1 and become stupid only when it is a multiple of 3 (feel the times ..)
Stream.iterate(1, n -> n + 1).limit(100)
.map(n -> n % 3 == 0 ? "Stupid" : n)
.forEach(System.out::println);
Intermediate operations are processing such as filtering and executing functions for each element of the array.
The intermediate operation can be repeated many times. After filtering, process with map etc.
Please note that the return value of the intermediate operation will be stream
You can * filter * elements under certain conditions by using filter (). The following is a usage example.
Output only even numbers from the array
//Target list
List<Integer> numberList = Arrays.asList(8, 1, 4, 2, 9);
//Output even numbers for statement
for (Integer number : numberList) {
if (number % 2 == 0) {
System.out.println(number);
}
}
//Output even numbers Stream
numberList.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
Doubles each element of the array and outputs it
List<Integer> numberList = Arrays.asList(8, 1, 4, 2, 9);
//Output by doubling each element for statement
for (Integer number : numberList) {
System.out.println(number * 2);
}
//Double each element for output Stream
numberList.stream()
.map(n -> n * 2)
.forEach(System.out::println);
Sorting elements is also easy if you use sort.
List<Integer> numberList = Arrays.asList(8, 1, 4, 2, 9);
List<Integer> sortListAsc = numberList.stream().sorted().collect(Collectors.toList());
List<Integer> sortListDesc = numberList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
System.out.println(sortListAsc);
// [1, 2, 4, 8, 9]
System.out.println(sortListDesc);
// [9, 8, 4, 2, 1]
For the termination operation, you can execute the function sequentially using stream
The following is a typical example.
You can use collect to convert a Stream to various types and get the result.
Double the element and receive the result as an array
List<Integer> numberList = Arrays.asList(8, 1, 4, 2, 9);
List<Integer> doubleList = numberList.stream()
.map(n -> n * 2)
.collect(Collectors.toList());
System.out.println(doubleList); //[16, 2, 8, 4, 18]
Judge the value and create a map called [value, "even" or "odd"].
List<Integer> numberList = Arrays.asList(8, 1, 4, 2, 9);
Map<Integer, String> demoMap = numberList.stream()
.collect(Collectors.toMap(
n -> n,
s -> s % 2 == 0 ? "Even" : "Odd"));
System.out.println(demoMap); //{1=Odd, 2=Even, 4=Even, 8=Even, 9=Odd}
Standard output as it is
List<Integer> numberList = Arrays.asList(8, 1, 4, 2, 9);
//Both are the same
numberList.stream().forEach(n -> System.out.println(n));
numberList.stream().forEach(System.out::println);
http://www.task-notes.com/entry/20150518/1431918000 https://qiita.com/nmby/items/52d1b0e2dad5df475737 http://aoking.hatenablog.jp/entry/20110810/1312970979 https://qiita.com/kumazo/items/104fa685da8705b8cfd8#36-flatmap
Recommended Posts