From |
You can create streams from collections, arrays, generators, or iterators.
|
To |
You can collect stream results in collections, arrays, strings, or maps.
|
Operations |
Specify intermediate operations for transforming the initial stream into
others, possibly in multiple steps. Intermediate - return Streams objects.
Apply a terminal (reduction) operation to produce a result. This operation forces the execution of the lazy operations that precede it. Afterwards, the stream can no longer be used.
|
Collection -> Stream
Use method .stream() |
List<String> words = List.of("I", "am", "a", "list", "of", "Strings"); // OR
List<String> words = List.of(contents.split("\\PL+")); // Split into words; nonletters are delimiters
Stream<String> stream = strings.stream();
|
Array -> Stream
Use method Stream.of() |
Stream<String> words = Stream.of(contents.split("\\PL+")); // split returns a String[] array
Stream<String> song = Stream.of("gently", "down", "the", "stream");
|
Empty Stream
|
Stream<String> silence = Stream.empty(); // Generic type <String> is inferred; same as Stream.<String>empty()
|
Infinite Stream
.generate, .iterate
|
Stream<String> echos = Stream.generate(() -> "Echo"); // constant values
Stream<Double> randoms = Stream.generate(Math::random); // random
Stream<BigInteger> integers = Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.ONE)); // 1 2 3 ...
// To produce a finite stream instead, add a predicate that specifies when the iteration should finish:
BigInteger limit = new BigInteger("10000000");
Stream<BigInteger> integers = Stream.iterate(BigInteger.ZERO, n -> n.compareTo(limit) < 0, n -> n.add(BigInteger.ONE));
|
filter, map, and flatMap
every transformation yelds a new stream |
To filter
List words = List.of(contents.split("\\PL+"));
Stream longWords = words.stream().filter(w -> w.length() > 12);
To transform use the map
method and pass the function that carries out the transformation.
Stream lowercaseWords = words.stream().map(String::toLowerCase); // OR
Stream firstLetters = words.stream().map(s -> s.substring(0, 1));
a function is applied to each element, and the result is a new stream with the results. If Input of the function is a nested structure (List of Lists, Stream of Streams) the result would be stream of streams. With .flatMap() - the result would be flat Stream
Examples
List<String> myList = Stream.of("a", "b").map(String::toUpperCase).collect(Collectors.toList());
// Result is List "A","B"
List<List<String>> list = Arrays.asList( Arrays.asList("a"), Arrays.asList("b"));
List<Stream<String>> myList2 = list.stream().map(Collection::stream).collect(Collectors.toList());
// The type would be List<Stream<String>> not List of Lists or Strings
List<String> myList2 = list.stream().flatMap(Collection::stream).collect(Collectors.toList());
// flatMap - eliminate nested Streams
List<String> myList3 = list.stream().flatMap(Collection::stream).map(String::toUpperCase).collect(Collectors.toList());
// The right way to uppercase and flatten
// flatMap can be applied to Optional also to avoid nested Optionals
assertEquals(Optional.of("STRING"), Optional.of("string").flatMap(s -> Optional.of("STRING")));
|
Extracting Substreams and Combining Streams
.limit(n)
.skip(n)
.takeWhile()
.dropWhile()
concat
|
stream.limit(n) returns a new stream that ends after n elements. Can cut infinite stream to a size
Stream<Double> randoms = Stream.generate(Math::random).limit(100);
stream.skip(n) does the exact opposite. It discards the first n elements.
Stream<String> words = Stream.of(contents.split("\\PL+")).skip(1);
stream.takeWhile(predicate) call takes all elements from the
stream while the predicate is true, and then stops.
List<String> lista= Arrays.asList(" ","hola","que","tal","estas","hoy","aqui");
lista.stream().takeWhile((s)->s.length()<5).forEach(System.out::println);
dropWhile method does the opposite, dropping elements while a
condition is true and yielding a stream of all elements starting with the first one
for which the condition was false.
lista.stream().dropWhile(s -< s.trim().length() == 0).forEach(System.out::println);
You can concatenate two streams with the static concat method of the
Stream class
Stream.concat(Stream.of("hola","que"), Stream.of("tal","estas")).forEach(System.out::println);
Of course, the first stream should not be infinite - otherwise the second wouldn’t
ever get a chance.
|
.distinct()
.sorted()
.peek()
|
Stream<String> uniqueWords = Stream.of("merrily", "merrily", "merrily", "gently").distinct();
Different sorted method: for streams of Comparable elements, or with a
Comparator. Here, we sort strings so that the longest ones come first:
Stream<String> longestFirst = words.stream().sorted(Comparator.comparing(String::length).reversed());
peek method yields another stream with the same elements as the
original, but a function is invoked every time an element is retrieved. That is
handy for debugging
Object[] powers = Stream.iterate(1.0, p -> p * 2).peek(e -> System.out.println("Fetching " + e)).limit(20).toArray();
|
Simple Reductions
.max()
.min()
.count()
.findFirst()
.findAny()
.anyMatch()
|
No, singleton beans are not thread-safe, as thread safety is about execution, whereas the singleton is a design pattern focusing on creation. Thread safety depends only on the bean implementation itself. |
What are the autowiring modes?
Autowiring enables the programmer to inject the bean automatically. We don't need to write explicit injection logic.
|
1) | no | this is the default mode, it means autowiring is not enabled. |
2) | byName | injects the bean based on the property name. It uses setter method. |
3) | byType | injects the bean based on the property type. It uses setter method. |
4) | constructor | It injects the bean using constructor |
|
Spring Bean Life Cycle |
 |