The key aspect of Stream API is it’s the ability to perform very sophisticated operations such as search, filter, map, or otherwise manipulate data. Stream API is used to process collections of objects. A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result.
As a general rule, a stream operation by itself does not modify the data source. For example, sorting a stream does not change the order of the source. Rather, sorting stream results in creating a new stream that produces the sorted result.
Features:
Intermediate Operations On Streams (Intermediate operation is lazily executed and returns a stream as a result, hence various intermediate operations can be pipelined.)
List number = Arrays.asList(2,3,4,5); List square = number.stream().map(x->x*x).collect(Collectors.toList()); String number = Stream.of(9, 4, 6, 1, 3, 5).map(num -> num + "").collect(Collectors.joining(",")); // 9,4,6,1,3,5 double average = Stream.of("1","5","10","4").mapToInt(Integer::parseInt).average().getAsDouble(); // 5
List names = Arrays.asList("Reflection","Collection","Stream"); List result = names.stream().filter(s->s.startsWith("S")).collect(Collectors.toList());
List names = Arrays.asList("Reflection","Collection","Stream"); List result = names.stream().sorted().collect(Collectors.toList()); List<Integer> numbers = Stream.of(9,4,6,1,3,5).sorted((a, b) -> { return a.compareTo(b); }).collect(Collectors.toList()); System.out.println("numbers: " + numbers.toString());
numbers: [1, 3, 4, 5, 6, 9]
Terminal Operations On Streams(Terminal operations mark the end of the stream and return the result)
List number = Arrays.asList(2,3,4,5,3); Set square = number.stream().map(x->x*x).collect(Collectors.toSet()); Set<Integer> set = Stream.of(1, 2, 3).collect(Collectors.toCollection(HashSet::new)); //[1, 2, 3] Map<Integer,String> map = Stream.of(1, 2, 3).collect(Collectors.toConcurrentMap(num -> num, num -> num+"")); //{1=1, 2=2, 3=3}
List number = Arrays.asList(2,3,4,5); number.stream().map(x->x*x).forEach(y->System.out.println(y));
List number = Arrays.asList(2,3,4,5); int even = number.stream().filter(x->x%2==0).reduce(0,(ans,i)-> ans+i);
int initialValue = 5; int reducedNumber = Stream.of(1, 2, 3).reduce(initialValue, (num, index)-> { System.out.println("num: "+num+", index: "+index); return index; }); System.out.println("reducedNumber: "+reducedNumber);
num: 3, index: 1 num: 1, index: 2 num: 2, index: 3 reducedNumber: 3
String listToString = Stream.of("Folau", "Kinga", "Laulau").collect(Collectors.joining(", ", "(", ")")); System.out.println("listToString: " + listToString);
listToString: (Folau, Kinga, Laulau)
Examples
foreach – terminal operation
Performs an action for each element of this stream.
List<String> words = Arrays.asList("I", "can", "program", "in", "Java"); words.stream().forEach(System.out::println);
allMatch() – terminal operation
Returns whether all elements of this stream match the provided predicate. May not evaluate the predicate on all elements if not necessary for determining the result. If the stream is empty then true
is returned and the predicate is not evaluated.
// Creating a list of Integers List<Integer> list = Arrays.asList(3, 4, 6, 12, 20); // Check if all elements of stream // are divisible by 3 or not using // Stream allMatch(Predicate predicate) boolean answer = list.stream().allMatch(n-> n % 3 ==0);
map() – intermediate operation
Returns a stream consisting of the results of applying the given function to the elements of this stream.
// Creating a list of Integers List<Integer> list = Arrays.asList(3, 6, 9, 12, 15); // Using Stream map(Function mapper) and // displaying the corresponding new stream list.stream().map(number -> number * 3).forEach(System.out::println)
collect() – terminal operation
Stream.collect() method used to receive elements from a stream and store them in a collection.
users.add(new User("John", "john@gmail.com",100000)); users.add(new User("Peter", "peter@gmail.com", 50000)); // find employees whose salaries are above 100000 List<User> filteredList = users.stream().filter(user->user.getSalary() > 100000).collect(Collectors.toList()); // Collections to Map Map<Integer, String> result1 = users.stream().collect( Collectors.toMap(User::getId, User::getName)); Map<Integer, String> result2 = users.stream().collect( Collectors.toMap(u -> u.getId(), u -> u.getName())); Map result3 = list.stream().collect( Collectors.toMap( u -> u.getName(), u -> u.getId(), (oldValue, newValue) -> oldValue, LinkedHashMap::new ));
int sum = Stream.of(1, 2, 3).collect(Collectors.summingInt(Integer::intValue)); System.out.println("sum: " + sum);
sum: 6
long count() – terminal operation
Returns the count of elements in this stream.
long count = Arrays.asList("I","can","program","in","java").stream().count(); System.out.printf("There are %d elements in the stream %n", count);
iterate() – intermediate operation
Create values on demand
//Stream.iterate(initial value, next value) Stream.iterate(0, n -> n + 1) .limit(10) .forEach(x -> System.out.println(x)); int numOfIterations = 5; int initialValue = 3; Stream.iterate(initialValue, n -> { return n * 2; }).limit(numOfIterations).forEach(x -> System.out.println(x));
Stream Creation
Stream.of("Folau", "Kinga", "Laulau").forEach((name) -> { System.out.println("name1: " + name); }); Stream.builder().add("Folau").add("Kinga").add("Laulau").build().forEach((name) -> { System.out.println("name2: " + name); });
findFirst()
findFirst() returns the first element in the stream.
Stream.of("Folau", "Kinga", "Laulau").filter(name -> name.contains("lau")).forEach((name) -> { System.out.println("name: " + name); }); //name: Folau //name: Laulau
parallel – run executions in multiple threads.
int numOfIterations = 20; int initialValue = 3; int sum = Stream.iterate(initialValue, n -> { return n * 2; }).limit(numOfIterations).parallel().collect(Collectors.summingInt(Integer::intValue)); System.out.println("sum: " + sum);
Resources