Although the Stream API implemented from Java 8 is a very useful feature, Since I am often addicted to Stream-specific processing, I will describe the countermeasures
Basically, it's enough to remember only the following patterns -Convert from Collection to Stream -Convert from array & variadic arguments to Stream -Calling IntStream
Basic Stream call
// Collection(List/Set etc.)in the case of
Collection<BigDecimal>list = List.of(BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN);
Stream<BigDecimal>stream = list.stream();
//For arrays
BigDecimal[] array = new BigDecimal[] {BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN};
Stream<BigDecimal>stream = Stream.of(array);
//For variadic arguments(Same method as for array is OK)
Stream<BigDecimal>stream = Stream.of(BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN);
//When performing int loop processing * for(int i=0; i<=100 i++)...Equivalent processing
IntStream stream = IntStream.rangeClosed(0, 100);
Events that tend to occur when Stream starts
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
Stream must be converted to another type (termination processing) after processing. It is impossible to keep / reuse in the state of Stream like List
Stream cannot be reused
Stream<String>stream = Stream.of("","","");
//If you do something, the Stream will close (there is no workaround)
stream.collect(Collectors.toCollection(ArrayDeque::new));
//Streams that are already closed cannot be reused
stream.count();
//Stack trace
//Exception in thread "main" java.lang.IllegalStateException: stream has already been //operated upon or closed
// at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229)
// at java.base/java.util.stream.ReferencePipeline.count(ReferencePipeline.java:538)
// at main.TestFunc.main(TestFunc.java:11)
Action 1: Do not use Stream for variables and return values. Convert to Stream every time using Collection (List etc.) or Map
Workaround example
//After putting the variable in some collection...
List<BigDecimal> list = List.of(BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN);
//Convert to list
Deque<BigDecimal> deque = list.stream().collect(Collectors.toCollection(ArrayDeque::new));
//Count the number. Create a Stream for each process
long count = list.stream().count();
Correspondence 2: (Special example) Processing such as Average, Sum, and Count can be processed collectively.
Utilization of Summary Statistics
List<BigDecimal> list = List.of(BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN);
//Convert to Summary Statistics. There is no Decimal Summary Statistics
IntSummaryStatistics summary = list.stream().collect(Collectors.summarizingInt(BigDecimal::intValueExact));
//Multiple results can be obtained from one Stream process
summary.getMax();
summary.getAverage();
summary.getSum();
For example, there is no method to sum () for Stream \
Example without corresponding method
//There is no such method
Stream.of(1,2,3).sum();
Correspondence 1 (in the case of ** basic type **): Use a special Stream dedicated to the basic type
Example of converting to IntStream
//Convert to IntStream with mapToInt → Use the method that IntStream has specially
Stream.of(1, 2, 3).mapToInt(e -> e).sum();
Correspondence 2 (in the case of ** other than basic type **): Perform processing using Stream method or Collector
Example of adding with Decimal
//pattern 1:Processing to add all Decimal values in Stream with initial value 0=Performs the process of calculating the total. Processing method similar to the conventional for statement
Stream.of(1, 2, 3).map(BigDecimal::valueOf).reduce(BigDecimal.ZERO,BigDecimal::add);
//Pattern 2:Prepare a Collector and use it. Effective when you want to reuse it many times
Collector<BigDecimal, ?, BigDecimal> sum = Collectors.reducing(BigDecimal.ZERO, BigDecimal::add);
Stream.of(1, 2, 3).map(BigDecimal::valueOf).collect(sum);
Stream.of(BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN).collect(sum);
Basically, it's enough to remember only the following patterns -Convert from Stream to Collection -Convert from Stream to array
Conversion from Stream
// List(unspecified)in the case of
List<BigDecimal> list = Stream.of(BigDecimal.ZERO, BigDecimal.ONE).limit(1).collect(Collectors.toList());
//For other collections
Deque<BigDecimal> deque = Stream.of(BigDecimal.ZERO, BigDecimal.ONE).limit(1).collect(Collectors.toCollection(LinkedList::new));
//For arrays
BigDecimal[] array = Stream.of(BigDecimal.ZERO, BigDecimal.ONE).limit(1).toArray(BigDecimal[]::new);
In the FindFirst method, the result may be null, so we enclose it in Optional and urge the programmer to define what to do when it is null. In the Optional state, it is not possible to process the contents (BigDecimal in the example below) (BigDecimal.add (), etc.). At the moment, there is no such processing method other than Stream, so it is easy to get hooked.
Example of having to handle Optional
//error···[Type mismatch: Optional<BigDecimal>Cannot be converted to BigDecimal]
BigDecimal first = Stream.of(BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN).findFirst();
Correspondence: Add a method to extract the contents from Optional
Example of processing Optional
//If you also assume that there are no elements(This time, if there is no element, set it to 0)
BigDecimal first = Stream.of(BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN).findFirst().orElse(BigDecimal.ZERO);
//When there is no element unless an abnormality occurs(Throw NoSuchElementException)
BigDecimal first = Stream.<BigDecimal>of().findFirst().get();
//When there is no element unless an abnormality occurs(Throw the specified exception)
BigDecimal first = Stream.<BigDecimal>of().findFirst().orElseThrow(IllegalStateException::new);
Recommended Posts