Java Tutorials for Freshers and Experience developers, Programming interview Questions, Data Structure and Algorithms interview Programs, Kotlin programs, String Programs, Java 8 Stream API, Spring Boot and Troubleshooting common issues.
Tuesday, December 14, 2021
Java 8 Streams Filter With Multiple Conditions Examples
Saturday, December 11, 2021
Java 8 Streams if else logic
1. Overview
Friday, December 10, 2021
Java 8 Stream Collect() Examples
1. Overview
2. Java 8 Stream Collect() to List using Collectors.toList()
package com.javaprogramto.java8.collectors.collect; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; /** * Examples to Java 8 Stream collect() method * * @author JavaProgramTo.com * */ public class StreamCollectExample { public static void main(String[] args) { List<String> words = Arrays.asList("hello", "how", "are", "you", "doing", "mate"); List<String> list = words.stream() .map(word -> word.toUpperCase()) .collect(Collectors.toList()); System.out.println("Collectors.toList() : "+list); } }
Collectors.toList() : [HELLO, HOW, ARE, YOU, DOING, MATE]
3. Java 8 Stream Collect() to Set using Collectors.toSet()
List<String> numbers = Arrays.asList("one", "two", "one", "two", "three", "four"); // using toSet() Set<String> set = numbers.stream() .filter(number -> number.length() == 3) .collect(Collectors.toSet()); // without duplicates System.out.println("Set removes the duplicates : "); set.forEach(System.out::println); // using toList() List<String> list2 = numbers.stream() .filter(number -> number.length() == 3) .collect(Collectors.toList()); // without duplicates System.out.println("List with duplicates: "); list2.forEach(System.out::println);
Set removes the duplicates : one two List with duplicates: one two one two
4. Java 8 Stream Collect() to Map using Collectors.toMap()
List<String> words = Arrays.asList("hello", "how", "are", "you", "doing", "mate"); Map<String, Integer> wordsLength = words.stream() .collect(Collectors.toMap(Function.identity(), String::length)); System.out.println("toMap() output: "); wordsLength.forEach((key, value) -> System.out.println(key + " = "+value));
toMap() output: how = 3 doing = 5 are = 3 mate = 4 hello = 5 you = 3
List<String> numbers = Arrays.asList("one", "two", "one", "two", "three", "four");
Exception in thread "main" java.lang.IllegalStateException: Duplicate key one (attempted merging values 3 and 3) at java.base/java.util.stream.Collectors.duplicateKeyException(Collectors.java:133) at java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$1(Collectors.java:180) at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169) at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) at com.javaprogramto.java8.collectors.collect.StreamCollectExample.main(StreamCollectExample.java:45)
Map<String, String> wordsCount = numbers.stream() .collect(Collectors.toMap(Function.identity(), Function.identity(), (oldValue, newValue) -> oldValue+" repeated")); System.out.println("toMap() with dupolicates: "); wordsCount.forEach((key, value) -> System.out.println(key + " = "+value));
toMap() with duplicates: four = four one = one repeated three = three two = two repeated
5. Java 8 Stream Collect() to Collection such as LinkedList or TreeSet using Collectors.toCollection()
// toCollection() examples // to linkedlist List<String> linkedList = words.stream() .collect(Collectors.toCollection(LinkedList::new)); System.out.println("linkedList is instance of LinkedList = "+(linkedList instanceof LinkedList)); // to linkedhashset Set<String> linkedhHashSet = words.stream(). collect(Collectors.toCollection(LinkedHashSet::new)); System.out.println("linkedhHashSet is instance of LinkedHashSet = "+(linkedhHashSet instanceof LinkedHashSet)); // to linkedhashset Map<String, Integer> treeMap = words.stream() .collect(Collectors.toMap(Function.identity(), String::length, (oldValue, newValue) -> newValue, TreeMap::new)); System.out.println("treeMap is instance of TreeMap = "+(treeMap instanceof TreeMap));
linkedList is instance of LinkedList = true linkedhHashSet is instance of LinkedHashSet = true treeMap is instance of TreeMap = true
6. Java 8 Stream API Collect Full Examples
package com.javaprogramto.java8.collectors.collect; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.function.Function; import java.util.stream.Collectors; /** * Examples to Java 8 Stream collect() method * * @author JavaProgramTo.com * */ public class StreamCollectExample { public static void main(String[] args) { // toList() examples List<String> words = Arrays.asList("hello", "how", "are", "you", "doing", "mate"); List<String> list = words.stream() .map(word -> word.toUpperCase()) .collect(Collectors.toList()); System.out.println("Collectors.toList() : "+list); List<String> numbers = Arrays.asList("one", "two", "one", "two", "three", "four"); // using toSet() Set<String> set = numbers.stream().filter(number -> number.length() == 3).collect(Collectors.toSet()); // without duplicates System.out.println("Set removes the duplicates : "); set.forEach(System.out::println); // using toList() List<String> list2 = numbers.stream().filter(number -> number.length() == 3).collect(Collectors.toList()); // without duplicates System.out.println("List with duplicates: "); list2.forEach(System.out::println); // tomap() examples Map<String, Integer> wordsLength = words.stream().collect(Collectors.toMap(Function.identity(), String::length)); System.out.println("toMap() output: "); wordsLength.forEach((key, value) -> System.out.println(key + " = "+value)); Map<String, String> wordsCount = numbers.stream().collect(Collectors.toMap(Function.identity(), Function.identity(), (oldValue, newValue) -> oldValue+" repeated")); System.out.println("toMap() with duplicates: "); wordsCount.forEach((key, value) -> System.out.println(key + " = "+value)); // toCollection() examples // to linkedlist List<String> linkedList = words.stream().collect(Collectors.toCollection(LinkedList::new)); System.out.println("linkedList is instance of LinkedList = "+(linkedList instanceof LinkedList)); // to linkedhashset Set<String> linkedhHashSet = words.stream().collect(Collectors.toCollection(LinkedHashSet::new)); System.out.println("linkedhHashSet is instance of LinkedHashSet = "+(linkedhHashSet instanceof LinkedHashSet)); // to linkedhashset Map<String, Integer> treeMap = words.stream().collect(Collectors.toMap(Function.identity(), String::length, (oldValue, newValue) -> newValue, TreeMap::new)); System.out.println("treeMap is instance of TreeMap = "+(treeMap instanceof TreeMap)); } }
7. Conclusion
Wednesday, December 1, 2021
Java 8 IllegalStateException “Stream has already been operated upon or closed” Exception (Stream reuse)
1. Overview
In this short tutorial, We'll see the most common exception "java.lang.IllegalStateException: stream has already been operated upon or closed". We may encounter this exception when working with the Stream interface in Java 8.Sunday, November 28, 2021
Java 8 Stream map() examples - Stream Conversions
1. Overview
In this article, we'll be learning about a new map() function in Java 8 that is introduced in Stream API. map() method converts a Stream from one form to another Stream. This takes input X type Stream and converts into Y type output Stream.
This is widely used as part of new JDK 8 api.
Friday, November 26, 2021
Java 8 Streams - Join or Append Stream of Strings using Collectors.joining()
1. Overview
2. Collectors.joining() Method
public static Collector<CharSequence,?,String> joining() public static Collector<CharSequence,?,String> joining(CharSequence delimiter) public static Collector<CharSequence,?,String> joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
3. Java 8 Stream Join String Examples
package com.javaprogramto.java8.streams.join; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; /** * Java Join Stream Of Strings and stream to string examples. * * @author JavaProgramTo.com * */ public class StreamOfStringJoiningExample { public static void main(String[] args) { // Creating the List with string values using Arrays.asList() method List<String> stringsList = Arrays.asList("1", "2", "3", "4", "5"); // java 8 join stream of strings or stream to string // Example - 1: with default delimiter String joinWithDefaultDelimiter = stringsList.stream().collect(Collectors.joining()); // Example - 2: with delimiter String joinWithDelimiter = stringsList.stream().collect(Collectors.joining(":")); // Example - 3: with given delimiter, suffix and prefix String joinWithDelimiterSuffixPrefix = stringsList.stream().collect(Collectors.joining("|", "[", "]")); // printing the values System.out.println("Input List of strings : " + stringsList); System.out.println("joining() string : " + joinWithDefaultDelimiter); System.out.println("joining(delimiter) string : " + joinWithDelimiter); System.out.println("joining(delimiter, suffix, prefix) string : " + joinWithDelimiterSuffixPrefix); } }
Input List of strings : [1, 2, 3, 4, 5] joining() string : 12345 joining(delimiter) string : 1:2:3:4:5 joining(delimiter, suffix, prefix) string : [1|2|3|4|5]
4. Stream IllegalStateException: stream has already been operated upon or closed
// Creating the stream object once and reuse for every collect() call. Stream<String> stream = stringsList.stream(); // java 8 join stream of strings or stream to string // Example - 1: with default delimiter String joinWithDefaultDelimiter = stream.collect(Collectors.joining()); // Example - 2: with delimiter String joinWithDelimiter = stream.collect(Collectors.joining(":")); // Example - 3: with given delimiter pipe(|), suffix and prefix String joinWithDelimiterSuffixPrefix = stream.collect(Collectors.joining("|", "[", "]"));
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.collect(ReferencePipeline.java:578) at com.javaprogramto.java8.streams.join.StreamOfStringJoiningExample.main(StreamOfStringJoiningExample.java:29)
5. Conclusion
Wednesday, November 24, 2021
Stream to Array - How To Convert Stream To Array In Java 8?
1. Overview
In this article, we'll explore the different ways to convert Stream to Array in Java 8.
I have shown in the previous article how to convert ArrayList<String> to String[] array in java 8.
Java 8 Stream api provides a method Stream.toArray() method which converts the string to array in a faster way.
Stream.of(String t) method is used to create Stream of Strings as Stream<String>.
We will be showing the conversion on the following in this article
1.1 Using Method Reference
1.2 Lambda Expression
1.3 Custom class stream to custom class array
1.4 On primitive types
But, for all the cases, you must use the Stream.toArray() method.
Stream.toArray() Syntax:
<A> A[] toArray(IntFunction<A[]> generator);
Let us explore each of these topics. In this article, We are going to show examples of how to convert Stream of String into a String array. But, you can convert any Stream of objects into any typed array.
Below all are possible with the toArray() method.
Example 1: Convert Stream<String> to String[] array
Example 2: Convert Stream<Employee> to Employee[] array
Example 3: Convert Stream<CustomClass> to CustomClass[] array
Example 4: Convert Stream<Integer> to Integer[] wrapper Integer array
Example 5: Convert Stream<Integer> to int[] primitive array
2. Using Method Reference
Method Reference is a broad topic. You can go through this article for an advanced level.
Method ref is indicated with "::" double colon operator introduced in java 8 and used to create an instance for a class.
Let us write a simple method with Method reference.
public static String[] convertStreamToArray(Stream<String> stringStream){
String[] strArray = stringStream.toArray(String[]::new);
return strArray;
}
Next, write the code to test this method working fine or not.import java.util.Arrays;
import java.util.stream.Stream;
public class MethodRefStreamToArray {
public static void main(String[] args) {
Stream<String> stringStream = Stream.of("hello", "reader", "welcome", "to", "javaprogramto.com", "blog");
String[] array1 = convertStreamToArray(stringStream);
System.out.println("Array 1 : "+ Arrays.toString(array1));
Stream<String> stringStream2 = Stream.of("seocond", "example", "stream to array");
String[] array2 = convertStreamToArray(stringStream2);
System.out.println("Array 2 : "+ Arrays.toString(array2));
}
public static String[] convertStreamToArray(Stream<String> stringStream) {
String[] strArray = stringStream.toArray(String[]::new);
return strArray;
}
}
Output:Array 1 : [hello, reader, welcome, to, javaprogramto.com, blog] Array 2 : [seocond, example, stream to array]
3. Using Lambda Expression
import java.util.Arrays;
import java.util.stream.Stream;
public class LambdaStreamToArray {
public static void main(String[] args) {
Stream<String> stringStream = Stream.of("hello", "reader", "welcome", "to", "javaprogramto.com", "blog");
String[] array1 = convertStreamToArrayWithLambda(stringStream);
System.out.println("Array 1 : "+ Arrays.toString(array1));
Stream<String> stringStream2 = Stream.of("seocond", "example", "stream to array");
String[] array2 = convertStreamToArrayWithLambda(stringStream2);
System.out.println("Array 2 : "+ Arrays.toString(array2));
}
public static String[] convertStreamToArrayWithLambda(Stream<String> stringStream) {
String[] strArray = stringStream.toArray(size -> {
return new String[size];
});
return strArray;
}
}
This program produces the output as same as the above section.4. Using Custom Generator Class
import java.util.Arrays;
import java.util.function.IntFunction;
import java.util.stream.Stream;
public class CustomIntFunctionStreamToArray {
public static void main(String[] args) {
Stream<String> stringStream = Stream.of("hello", "reader", "welcome", "to", "javaprogramto.com", "blog");
String[] array1 = stringStream.toArray(new CustomIntFunction());
System.out.println("Array 1 : "+ Arrays.toString(array1));
Stream<String> stringStream2 = Stream.of("seocond", "example", "stream to array");
String[] array2 = stringStream2.toArray(new CustomIntFunction());;
System.out.println("Array 2 : "+ Arrays.toString(array2));
}
}
class CustomIntFunction implements IntFunction<String[]>{
@Override
public String[] apply(int size) {
return new String[size];
}
}
Output:Array 1 : [hello, reader, welcome, to, javaprogramto.com, blog]
Array 2 : [seocond, example, stream to array]
5. Stream to Primitive Or Wrapper Array conversion
Wrapper Stream to Wrapper[] Array Example
import java.util.Arrays; import java.util.stream.Stream; public class WrapperStreamToArray { public static void main(String[] args) { Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7); Integer[] array1 = integerStream.toArray(Integer[]::new); System.out.println("Integer Array 1 : " + Arrays.toString(array1)); Stream<Integer> integerStream2 = Stream.of(11, 22, 33, 44, 55); Integer[] array2 = integerStream2.toArray(size -> new Integer[size]); System.out.println("Integer Array 2 : " + Arrays.toString(array2)); } }Output:
Integer Array 1 : [1, 2, 3, 4, 5, 6, 7] Integer Array 2 : [11, 22, 33, 44, 55]
Integer[] array2 = integerStream2.toArray(size -> new Integer[0]);
Exception:Exception in thread "main" java.lang.IllegalStateException: Begin size 5 is not equal to fixed size 0 at java.base/java.util.stream.Nodes$FixedNodeBuilder.begin(Nodes.java:1222) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:483) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:550) at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260) at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:517) at com.javaprogramto.java8.streams.toarray.WrapperStreamToArray.main(WrapperStreamToArray.java:18)
Wrapper Stream to int[] primitive Array Example
import java.util.Arrays; import java.util.stream.Stream; public class PrimitiveStreamToArray { public static void main(String[] args) { Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7); int[] array1 = integerStream.mapToInt(primitiveVlaue -> primitiveVlaue).toArray(); System.out.println("int[] Array 1 : " + Arrays.toString(array1)); Stream<Integer> integerStream2 = Stream.of(11, 22, 33, 44, 55); int[] array2 = integerStream2.mapToInt( i -> i).toArray(); System.out.println("int[] Array 2 : " + Arrays.toString(array2)); } }
7. Exception
Array 1 : [hello, reader, welcome, to, javaprogramto.com, blog]Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:246) at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:517) at com.javaprogramto.java8.streams.toarray.CustomIntFunctionStreamToArray.main(CustomIntFunctionStreamToArray.java:19)
8. Conclusion
Wednesday, November 3, 2021
Java 8 Stream Sum - Adding Numbers With Java Streams
1. Overview
In this article, we'll learn how to add the numbers in java using java 8 streams summing and reduce() methods.
To make the examples simple, we are going to write code based in the integer values.
2. Sum using Java Stream.reduce()
First, Stream api has a reduce() method which takes the accumulator as an argument. reduce() method is a terminal operation which means reduce() method produces the result from stream and this should be called at the end of the stream.
reduce() method takes the two numbers such as number 1 and number 2. These two numbers are taken and applied the logic of addition what we write.
Please refer the following example program.
package com.javaprogramto.java8.streams.sum; import java.util.Arrays; import java.util.List; public class IntegerSumExample1 { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); int totalSum = numbers.stream().reduce(0, (number1, number2) -> number1 + number2); System.out.println("Sum of integers : "+totalSum); } }
Output
Sum of integers : 55
Instead of passing "(number1, number2) -> number1 + number2)" logic to the reduce method, you can add this logic in the new method and call the new method as below. There will be no change in the output. In this way, we can reuse the add() method from many stream operations.
public class IntegerSumExample1 { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); int totalSum = numbers.stream().reduce(0, ArithmeticUtils::add); System.out.println("Sum of integers : " + totalSum); } } class ArithmeticUtils { public static int add(int number1, int number2) { return number1 + number2; } }
Additionally, you can use the builtin method Integer::sum from the reduce() method.
3. Using Collectors.summingInt()
Another way to add the list of integers is using the summingInt() of Collectors api.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); int summingIntValue = numbers.stream().collect(Collectors.summingInt(Integer::intValue)); System.out.println("Sum of integers using summingInt : " + summingIntValue);
Output:
Sum of integers using summingInt : 55
In the similar to the summingInt(), there are separate methods to deal with the addition of long and double such as summingDouble() and summingLong().
4. Using IntStream.sum()
Next, Using IntStream api sum() method, we can get the addition of numbers from the list or map.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); int intStreamSum = numbers.stream().mapToInt(Integer::intValue).sum(); System.out.println("IntStream sum : "+intStreamSum);
Output:
IntStream sum : 55
5. Stream Sum with Map values
Let us see now to get the sum of value of Map object. First we need to get the values list or set from the map and then apply any one of the methods what we have learnt so far.
Map<Double, Integer> map = new HashMap<>(); map.put(1.0, 100); map.put(2.0, 200); map.put(3.0, 300); map.put(4.0, 400); int mapValuesSum = map.values().stream().reduce(0, Integer::sum); System.out.println("Map values sum : "+mapValuesSum);
Output:
Map values sum : 1000
6. Stream sum with custom objects
Next, create the set of objects then add them to the list. Further apply all of these ways on the list.
List<Employee> emps = Arrays.asList(new Employee(100, "A", 25), new Employee(200, "B", 35), new Employee(300, "C", 45)); int sum = emps.stream().map(emp -> emp.getAge()) .reduce(0, (a, b) -> a + b); sum = emps.stream().map(emp -> emp.getAge()) .mapToInt(Integer::intValue) .sum(); sum = emps.stream().map(emp -> emp.getAge()) .collect(Collectors.summingInt(Integer::intValue));
All above ways produces the same output as sum value 105.
7. Full code Stream Sum Example
All the examples are shown are put together in the single program.
package com.javaprogramto.java8.streams.sum; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import com.javaprogramto.models.Employee; public class IntegerSumExample1 { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // reduce() example int totalSum = numbers.stream().reduce(0, ArithmeticUtils::add); System.out.println("Sum of integers : " + totalSum); // summingInt() example int summingIntValue = numbers.stream().collect(Collectors.summingInt(Integer::intValue)); System.out.println("Sum of integers using summingInt : " + summingIntValue); // IntStream sum() example int intStreamSum = numbers.stream().mapToInt(Integer::intValue).sum(); System.out.println("IntStream sum : " + intStreamSum); Map<Double, Integer> map = new HashMap<>(); map.put(1.0, 100); map.put(2.0, 200); map.put(3.0, 300); map.put(4.0, 400); int mapValuesSum = map.values().stream().reduce(0, Integer::sum); System.out.println("Map values sum : " + mapValuesSum); List<Employee> emps = Arrays.asList(new Employee(100, "A", 25), new Employee(200, "B", 35), new Employee(300, "C", 45)); int sum = emps.stream().map(emp -> emp.getAge()) .reduce(0, (a, b) -> a + b); sum = emps.stream().map(emp -> emp.getAge()) .mapToInt(Integer::intValue) .sum(); sum = emps.stream().map(emp -> emp.getAge()) .collect(Collectors.summingInt(Integer::intValue)); System.out.println("custom objects sum : "+sum); } } class ArithmeticUtils { public static int add(int number1, int number2) { return number1 + number2; } }
Output
Sum of integers : 55 Sum of integers using summingInt : 55 IntStream sum : 55 Map values sum : 1000 custom objects sum : 105
8. Conclusion
In this post, we've seen what are the different ways to do sum of numbers using java stream api with examples.
Friday, February 5, 2021
Java 8 Parallel Streams - Custom Thread Pools Examples
1. Introduction
In this tutorial, You'll learn how to create custom thread pools in Java 8 for bulk data processing with parallel streams powerful API.
Parallel Stream can work well in concurrent environments and these are improved versions of streams performance at the cost of multi-threading overhead.
The main focus in this article is to look at one of the biggest limitations of Stream API and Examples on how can you use the Parallel Streams with the custom thread pools.
Thursday, December 10, 2020
Java 8 Stream - Convert List to Map
1. Overview
2. Collect List to Map using Collectors.toMap()
package com.javaprogramto.java8.arraylist.tomap; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; public class ListToMapExample { public static void main(String[] args) { // creating a List List<String> list = Arrays.asList("one","two","three","four","five"); // List to Stream Stream<String> stream = list.stream(); // Stream to map - key is the string and value is its length Map<String, Integer> map = stream.collect(Collectors.toMap(String::new, String::length)); // printing input list and map System.out.println("List : "+list); System.out.println("Map : "+map); } }
List : [one, two, three, four, five] Map : {four=4, one=3, two=3, three=5, five=4}
3. Collect List of Custom objects to Map using Collectors.toMap()
package com.javaprogramto.java8.arraylist.tomap; public class Book { private int id; private String author; private int yearRealeased; public Book(int id, String author, int yearRealeased) { this.id = id; this.author = author; this.yearRealeased = yearRealeased; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public int getYearRealeased() { return yearRealeased; } public void setYearRealeased(int yearRealeased) { this.yearRealeased = yearRealeased; } @Override public String toString() { return "Book [id=" + id + ", author=" + author + ", yearRealeased=" + yearRealeased + "]"; } }
package com.javaprogramto.java8.arraylist.tomap; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; public class ListToMapCustomObjects { public static void main(String[] args) { List<Book> books = Arrays.asList(new Book(100, "book 1", 2017), new Book(101, "book 2", 2018), new Book(102, "book 3", 2019), new Book(103, "book 4", 2020)); // map1 with key = id and value is book object Map<Integer, Book> map1 = books.stream().collect(Collectors.toMap(Book::getId, Function.identity())); // map2 with key = yearReleased and value is book object Map<Integer, Book> map2 = books.stream().collect(Collectors.toMap(Book::getYearRealeased, Function.identity())); // map3 with key = author name and value is year released Map<String, Integer> map3 = books.stream().collect(Collectors.toMap(Book::getAuthor, Book::getYearRealeased)); // printing System.out.println("List of books --> " + books); System.out.println("Map1 --> " + map1); System.out.println("Map2 --> " + map2); System.out.println("Map3 --> " + map3); } }
List of books --> [Book [id=100, author=book 1, yearRealeased=2017], Book [id=101, author=book 2, yearRealeased=2018], Book [id=102, author=book 3, yearRealeased=2019], Book [id=103, author=book 4, yearRealeased=2020]] Map1 --> {100=Book [id=100, author=book 1, yearRealeased=2017], 101=Book [id=101, author=book 2, yearRealeased=2018], 102=Book [id=102, author=book 3, yearRealeased=2019], 103=Book [id=103, author=book 4, yearRealeased=2020]} Map2 --> {2017=Book [id=100, author=book 1, yearRealeased=2017], 2018=Book [id=101, author=book 2, yearRealeased=2018], 2019=Book [id=102, author=book 3, yearRealeased=2019], 2020=Book [id=103, author=book 4, yearRealeased=2020]} Map3 --> {book 2=2018, book 1=2017, book 4=2020, book 3=2019}
4. List to Map with Duplicate key
List<String> list = Arrays.asList("one","two","three","four","five", "five");
Exception in thread "main" java.lang.IllegalStateException: Duplicate key five (attempted merging values 4 and 4) at java.base/java.util.stream.Collectors.duplicateKeyException(Collectors.java:133) at java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$1(Collectors.java:180) at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169) at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) at com.javaprogramto.java8.arraylist.tomap.DuplicatesListToMapExample.main(DuplicatesListToMapExample.java:20)
Map<String, Integer> map = stream .collect(Collectors.toMap(String::new, String::length, (oldValue, newValue) -> newValue + 1000));
Map : {four=4, one=3, five=1004, three=5, two=3}
public class DuplicateListToMapCustomObjects { public static void main(String[] args) { List<Book> books = Arrays.asList(new Book(100, "book 1", 2017), new Book(101, "book 2", 2018), new Book(102, "book 3", 2019), new Book(103, "book 4", 2020), new Book(103, "book 3", 2021), new Book(102, "book 4", 2019)); // map1 with key = id and value is book object Map<Integer, Book> map1 = books.stream() .collect(Collectors.toMap(Book::getId, Function.identity(), (oldValue, newValue) -> newValue)); // map2 with key = yearReleased and value is book object Map<Integer, Book> map2 = books.stream().collect( Collectors.toMap(Book::getYearRealeased, Function.identity(), (oldValue, newValue) -> newValue)); // map3 with key = author name and value is year released Map<String, Integer> map3 = books.stream() .collect(Collectors.toMap(Book::getAuthor, Book::getYearRealeased, (oldValue, newValue) -> newValue)); // printing System.out.println("List of books --> " + books); System.out.println("Map1 --> " + map1); System.out.println("Map2 --> " + map2); System.out.println("Map3 --> " + map3); } }
List of books --> [Book [id=100, author=book 1, yearRealeased=2017], Book [id=101, author=book 2, yearRealeased=2018], Book [id=102, author=book 3, yearRealeased=2019], Book [id=103, author=book 4, yearRealeased=2020], Book [id=103, author=book 3, yearRealeased=2021], Book [id=102, author=book 4, yearRealeased=2019]] Map1 --> {100=Book [id=100, author=book 1, yearRealeased=2017], 101=Book [id=101, author=book 2, yearRealeased=2018], 102=Book [id=102, author=book 4, yearRealeased=2019], 103=Book [id=103, author=book 3, yearRealeased=2021]} Map2 --> {2017=Book [id=100, author=book 1, yearRealeased=2017], 2018=Book [id=101, author=book 2, yearRealeased=2018], 2019=Book [id=102, author=book 4, yearRealeased=2019], 2020=Book [id=103, author=book 4, yearRealeased=2020], 2021=Book [id=103, author=book 3, yearRealeased=2021]} Map3 --> {book 2=2018, book 1=2017, book 4=2019, book 3=2021}
5. Conclusion
Java 8 - How To Convert Any Stream to List in Java? toList()?
1. Overview
2. Java 8 - Convert Stream to List
package com.javaprogramto.java8.collectors.streamtolist;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Example Stream to List
*
* @author javaprogramto.com
*
*/
public class StreamToListExample {
public static void main(String[] args) {
// creating an list
List<String> names = Arrays.asList("Nick", "Boran", "Tison", "Sunshine");
// converting list to stream
Stream<String> stream = names.stream();
// finally collecting the stream values into a list with any filtering the
// objects.
List<String> finalList = stream.collect(Collectors.toList());
// printing
System.out.println("List values : " + finalList);
}
}
List values : [Nick, Boran, Tison, Sunshine]
3. Java 8 - Numbers Stream to List With filter() - Stream.of()
package com.javaprogramto.java8.collectors.streamtolist;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Example on numbers Stream to List
*
* @author javaprogramto.com
*
*/
public class NumbersStreamToListExample {
public static void main(String[] args) {
// Creating a stream using of() method.
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
// Filtering the stream values to get only even numbers and next collect into ArrayList.
List<Integer> finalList = stream.filter(e -> e % 2 == 0).collect(Collectors.toList());
// printing
System.out.println("Final ArrayList values : " + finalList);
}
}
Final ArrayList values : [2, 4]
4. Java 8 Stream to List as LinkedList
package com.javaprogramto.java8.collectors.streamtolist;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Example Stream to LinkedList
*
* @author javaprogramto.com
*
*/
public class StreamToLinkedListExample {
public static void main(String[] args) {
// creating an list
List<String> values = Arrays.asList("1", "2", "3", "4", "5");
// converting list to stream
Stream<String> stream = values.stream();
// Collecting the stream values into a LinkedList using stream collectors.
LinkedList<String> linkedList = stream.collect(Collectors.toCollection(LinkedList::new));
// printing
System.out.println("LinkedList values : " + linkedList);
}
}
LinkedList values : [1, 2, 3, 4, 5]
5. Java 8 - Convert Infinite Stream to List
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* Example on Infinite Stream to List
*
* @author javaprogramto.com
*
*/
public class StreamToListExample {
public static void main(String[] args) {
// Creating the infinite even numbers stream using iterate() starts from value
// 10.
IntStream infiniteStream = IntStream.iterate(10, i -> i + 2);
// limit() + boxed() + toList() example
List<Integer> finalList = infiniteStream.limit(10).boxed().collect(Collectors.toList());
// printing
System.out.println("List values : " + finalList);
}
}
List values : [10, 12, 14, 16, 18, 20, 22, 24, 26, 28]
6. Conclusion
Wednesday, December 9, 2020
Java 8 Stream foreach Collect - Can not be done?
1. Overview
2. Java 8 Stream forEach collect Example
package com.javaprogramto.java8.foreach; import java.util.ArrayList; import java.util.List; public class Java8StreamForEachCollect { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("hello"); list.add("world"); list.add("welcome"); list.add("to"); list.add("javaprogramto.com"); list.stream().filter(value -> value.contains("c")).forEach(value -> value + "-").collect(); } }
Exception in thread "main" java.lang.Error: Unresolved compilation problems: The method forEach(Consumer<? super String>) in the type Stream<String> is not applicable for the arguments ((<no type> value) -> {}) Void methods cannot return a value at com.javaprogramto.java8.foreach.Java8StreamForEachCollect.main(Java8StreamForEachCollect.java:18)
3. Solve - Stream forEach collect
package com.javaprogramto.java8.foreach; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class Java8StreamForEachCollect { public static void main(String[] args) { // creating a list List<String> list = new ArrayList<>(); // adding values to list list.add("hello"); list.add("world"); list.add("welcome"); list.add("to"); list.add("javaprogramto.com"); // list.stream().filter(value -> value.contains("c")).forEach(value -> value + // "-").collect(); // stream filter() + map() + collect() example List<String> newList = list.stream().filter(value -> value.contains("c")) .map(value -> value + "-") .collect(Collectors.toList()); //printing the list System.out.println("Original List : "+list); System.out.println("New List Values : "); // print using forEach on list. newList.forEach(value -> System.out.println(value)); // iterating stream using forEach() System.out.println("\niterating stream using forEach()"); list.stream().filter(value -> value.contains("c")) .map(value -> value + "-") .forEach(str -> System.out.println(str)); } }
Original List : [hello, world, welcome, to, javaprogramto.com] New List Values : welcome- javaprogramto.com- iterating stream using forEach() welcome- javaprogramto.com-
4. Conclusion
Saturday, November 21, 2020
Java 8 Stream findFirst() vs findAny() With Examples
1. Overview
List<String> values = Arrays.asList("A", "B", null, "F", "D"); Optional<String> anyValue = values.stream().findFirst();
Exception in thread "main" java.lang.NullPointerException at java.base/java.util.Objects.requireNonNull(Objects.java:221) at java.base/java.util.Optional.<init>(Optional.java:107) at java.base/java.util.Optional.of(Optional.java:120) at java.base/java.util.stream.FindOps$FindSink$OfRef.get(FindOps.java:194) at java.base/java.util.stream.FindOps$FindSink$OfRef.get(FindOps.java:191) at java.base/java.util.stream.FindOps$FindTask.doLeaf(FindOps.java:319) at java.base/java.util.stream.AbstractShortCircuitTask.compute(AbstractShortCircuitTask.java:115) at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746) at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) at java.base/java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:408) at java.base/java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:736) at java.base/java.util.stream.FindOps$FindOp.evaluateParallel(FindOps.java:160) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233) at java.base/java.util.stream.ReferencePipeline.findAny(ReferencePipeline.java:548) at com.javaprogramto.java8.streams.find.FindAnyParallelStreamIntegersExample.main(FindAnyParallelStreamIntegersExample.java:15)
2. Understand Usage of Stream.findAny()
Optional<T> findAny()
package com.javaprogramto.java8.streams.find; import java.util.Arrays; import java.util.List; import java.util.Optional; public class FindAnyExample { public static void main(String[] args) { // creating a list with string values List<String> values = Arrays.asList("A", "B", "C", "F", "D"); // getting the any value from stream. Optional<String> anyValue = values.stream().findAny(); // printing the value if (anyValue.isPresent()) { System.out.println("Any value from stream : " + anyValue.get()); } else { System.out.println("No value presnt in the stream."); } } }
Any value from stream : A
Optional<String> anyValue = values.stream().parallel().findAny();
Any value from stream : C
package com.javaprogramto.java8.streams.find; import java.util.Arrays; import java.util.List; import java.util.Optional; public class FindAnyParallelStreamIntegersExample { public static void main(String[] args) { // creating a list with integer prime values List<Integer> values = Arrays.asList(2, 3, 5, 7, 11); // Creating prallel stream. Optional<Integer> anyValue = values.stream().parallel().findAny(); // printing the value if (anyValue.isPresent()) { System.out.println("Value from integer stream : " + anyValue.get()); } else { System.out.println("No value presnt in the stream."); } } }
Value from integer stream : 5
3. Understand Usage of Stream.findFirst()
package com.javaprogramto.java8.streams.find; import java.util.Arrays; import java.util.List; import java.util.Optional; public class FindFirstSequentialExample { public static void main(String[] args) { // creating a list with string values List<String> values = Arrays.asList("A", "B", "C", "F", "D"); // Getting the first value from sequential stream using findFirst() method Optional<String> anyValue = values.stream().findFirst(); // printing the value if (anyValue.isPresent()) { System.out.println("First value from stream : " + anyValue.get()); } else { System.out.println("No value presnt in the stream."); } } }
First value from stream : A
package com.javaprogramto.java8.streams.find; import java.util.Arrays; import java.util.List; import java.util.Optional; public class FindFirstParallelExample { public static void main(String[] args) { // creating a list with string values List<String> values = Arrays.asList("A", "B", "C", "F", "D"); // Getting the first value from sequential stream using findFirst() method Optional<String> anyValue = values.stream().parallel().findFirst(); // printing the value if (anyValue.isPresent()) { System.out.println("First value from parallel stream : " + anyValue.get()); } else { System.out.println("No value presnt in the stream."); } } }
First value from parallel stream : A
4. Conclusion
Java 8 Stream - Distinct By Property Example
1. Overview
In this tutorial, you'll learn How to get the distinct values from collection using java 8 stream api distinct() method.
Read more on
In other words, how to remove the duplicates from list or collection using java 8 streams. This is a common tasks to avoid duplicates in the list. After java 8 roll out, it has become simple filtering using functional programming language.
Java 8 stream api is added with a unique distinct() method to remove the duplicate objects from stream.
distinct() is an intermediate operation that means it returns Stream<T> as output.
Next, let us jump into examples programs using Strings and Custom objects.
2. Java 8 distinct() example - Strings Values in List
First, create a simple list with duplicate string values. Now, we want to get only the unique values from it.
For this, we need to convert the list into stream using stream() method and next call distinct() method. Here, this distinct() method eliminates the duplicate string values.
Finally, invoke the Collectors.toList() method to take the distinct values into List.
import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class DistinctStringExample { public static void main(String[] args) { // create a list with string values List<String> strings = new ArrayList<>(); // adding values to list strings.add("ABC"); strings.add("XYZ"); strings.add("ABC"); strings.add("MNO"); strings.add("ABC"); strings.add("MNO"); strings.add("PQR"); // Getting the distinct values from stream using distinct() method List<String> uniqueStrings = strings.stream().distinct().collect(Collectors.toList()); //printing the values System.out.println("Original list : "+strings); System.out.println("Unique values list : "+uniqueStrings); } }
Output:
Original list : [ABC, XYZ, ABC, MNO, ABC, MNO, PQR] Unique values list : [ABC, XYZ, MNO, PQR]
3. Java 8 distinct() example - By Custom Object Property
In the above program, we've seen with the simple strings. But in the real time, you will be adding the real objects such as Employee, Trade or Customer objects.
Let us create a Customer class with id, name and phone number. Next, add 5 Customer objects to the List with duplicate id values.
Finally, use our custom logic will get only the distinct by id field using Function Functional interface.
Customer.java
package com.javaprogramto.java8.streams.distinct; public class Customer { private int id; private String name; private long phonenumber; public Customer(int id, String name, long phonenumber) { super(); this.id = id; this.name = name; this.phonenumber = phonenumber; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getPhonenumber() { return phonenumber; } public void setPhonenumber(long phonenumber) { this.phonenumber = phonenumber; } @Override public String toString() { return "Customer [id=" + id + ", name=" + name + ", phonenumber=" + phonenumber + "]"; } }
Distinct by Property Example:
package com.javaprogramto.java8.streams.distinct; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; public class DistinctByCustomPropertyExample { // predicate to filter the duplicates by the given key extractor. public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) { Map<Object, Boolean> uniqueMap = new ConcurrentHashMap<>(); return t -> uniqueMap.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; } public static void main(String[] args) { // creating customer objects with repeated id's 100, 101 Customer customer1 = new Customer(100, "Jhon", 675000000l); Customer customer2 = new Customer(101, "Peter", 675000001l); Customer customer3 = new Customer(100, "Paul", 675000002l); Customer customer4 = new Customer(102, "Noel", 675000003l); Customer customer5 = new Customer(101, "Nup", 675000004l); // created a list to store the customer objects List<Customer> customers = new ArrayList<>(); // adding customer objects customers.add(customer1); customers.add(customer2); customers.add(customer3); customers.add(customer4); customers.add(customer5); List<Customer> distinctElements = customers.stream().filter(distinctByKey(cust -> cust.getId())) .collect(Collectors.toList()); System.out.println("customers size : " + customers.size()); System.out.println("Distinct customers size : " + distinctElements.size()); } }
Output:
customers size : 5 Distinct customers size : 3In the above program, the core is the distinctByKey() method which does the job removing the duplicates.
This is the advantage of core functional programming language.
4. Java 8 distinct toMap() example - Distinct values collecting into Map
In the above example, we have stored the output into List with Customer objects. But, we want to store it into map with id as key and customer object as value.
Use Collectors.toMap() method to remove the duplicates and collect into map.
package com.javaprogramto.java8.streams.distinct; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class DistinctByMapExample { public static void main(String[] args) { // creating customer objects with repeated id's 100, 101 Customer customer1 = new Customer(100, "Jhon", 675000000l); Customer customer2 = new Customer(101, "Peter", 675000001l); Customer customer3 = new Customer(100, "Paul", 675000002l); Customer customer4 = new Customer(102, "Noel", 675000003l); Customer customer5 = new Customer(101, "Nup", 675000004l); // created a list to store the customer objects List<Customer> customers = Arrays.asList(customer1, customer2, customer3, customer4, customer5); // removing the duplicates and collecting into map id as key, customer as value Map<Integer, Customer> mapIdCustomer = customers.stream() .collect(Collectors.toMap(Customer::getId, c -> c, (c1, c2) -> c1)); // printing the map System.out.println("Final map after eliminating the duplicates - "+mapIdCustomer); } }
Output:
Final map after eliminating the duplicates -
{100=Customer [id=100, name=Jhon, phonenumber=675000000],
101=Customer [id=101, name=Peter, phonenumber=675000001],
102=Customer [id=102, name=Noel, phonenumber=675000003]}
5. Conclusion
In this short article, you've seen how to get the distinct values from collection and store them into List and Map.
GitHub
DistinctByCustomPropertyExample.java
Ref