Java8 / 9 Beginners: Stream API addiction points and how to deal with them

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

1. I don't know how to call Stream in the first place

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);

2. Addictive points that tend to occur without knowing

Events that tend to occur when Stream starts


Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed

2.1: IllegalStateException occurs ... Stream cannot be reused

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();

2.2 Stream has no type-specific methods

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);

2.3 I don't know how to return to an array / List / Map

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);

2.4 I don't know how to handle Optional

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

Java8 / 9 Beginners: Stream API addiction points and how to deal with them
[For beginners] How to operate Stream API after Java 8
Common problems with WSL and how to deal with them
How to use Java API with lambda expression
How to build API with GraphQL and Rails
[Java] How to operate List using Stream API
[Java] Types of comments and how to write them
[Java] Introduction to Stream API
[Must-see for apprentice java engineer] How to use Stream API
How to handle exceptions coolly with Java 8 Stream or Optional
Handle exceptions coolly with Java 8 lambda expressions and Stream API
How to call and use API in Java (Spring Boot)
Convert 2D array to csv format with Java 8 Stream API
How to deal with different versions of rbenv and Ruby
[java8] To understand the Stream API
[Java] Points to note with Arrays.asList ()
[Introduction to Java] About Stream API
Java, arrays to start with beginners
Java 8 ~ Stream API ~ to start now
Android: How to deal with "Could not determine java version from '10 .0.1'"
Project facet Java version 13 is not supported. How to deal with
How to encrypt and decrypt with RSA public key in Java
How to compile Java with VsCode & Ant
[Java] How to compare with equals method
[Android] How to deal with dark themes
Nowadays Java lambda expressions and Stream API
[Java] How to output and write files!
How to deal with Precompiling assets failed.
How to convert an array of Strings to an array of objects with the Stream API
[Node.js express Docker] How to define Docker environment variables and load them with node.js
How to make an app with a plugin mechanism [C # and Java]
twitter-4 selections of certain errors with Twitter login function created by omniauth gem and how to deal with them
Challenge to deal with garbled characters with Java AudioSystem.getMixerInfo ()
[Java] How to test for null with JUnit
[Java] How to use FileReader class and BufferedReader class
[Java] How to get and output standard input
Try to link Ruby and Java with Dapr
How to use Java framework with AWS Lambda! ??
Java Stream API
How to use Segmented Control and points to note
How to get and study java SE8 Gold
[For beginners] About lambda expressions and Stream API
Rails scope anti-patterns and how to eliminate them
How to access Java Private methods and fields
[Java] How to use Calendar class and Date class
A memo about the types of Java O/R mappers and how to select them
[Docker] How to update using a container on Heroku and how to deal with Migrate Error
How to call functions in bulk with Java reflection
List processing to understand with pictures --java8 stream / javaslang-
How to deal with fatal: remote origin already exists.
[Java] How to omit spring constructor injection with Lombok
How to deploy Java to AWS Lambda with Serverless Framework
[In-house study session] Java basics-Lambda expression and Stream API- (2017/07/13)
How to deal with No template for interactive request
[Docker environment] How to deal with ActiveSupport :: MessageEncryptor :: InvalidMessage
Java memory management and how to read GC Viewer
[Java] Refer to and set private variables with reflection
[Rails] How to deal with URL changes after render
How to serialize and deserialize LocalDateTime type with GSON
I want to transition screens with kotlin and java!
Summary of Java communication API (3) How to use SocketChannel