Consider a Book class, the goal is to create a Map<Integer, Book> from List<Book>
Debugging streams with peak
returns a stream consisting of the elements of this stream, additionally performing the provided action on each element as they are consumed from the resulting stream.
public class Person {
private String name;
public Person(){}
public Person (String name) {
this.name = name;
}
// other methods
}
List<Person> people = names.stream().map(Person::new).collect(Collectors.toList());
public Person (Person p) {
this.name = p.name;
}
Person before = new Person("Before");
List<Person> people = Stream.of(before).collect(Collectors.toList());
Person after = people.get(0);
assertTrue(before == after);
before.setName("changed");
assertEquals("changed", after.getName());
people = Stream.of(before).map(Person::new).collect(Collectors.toList());
Person after = people.get(0);
assertFalse(before == after);
assertEquals(before, after);
before.setName("changed");
assertFalse(before.equals(after));
People[] people = names.stream()
.map(Person::new) // constructor reference for Person
.toArray(Person[]::new); // constructor reference for array of Person
@java.lang.FunctionalInterface // provides compile-time check
public interface TheChecker {
boolean check(String s); // no need for abstract keyword
// int anotherMethod(); // if added => not a functional interface any more
default String sayHello() {
return "Hello";
}
static void theStaticMethod() {
System.out.println("I'm a static method in an interface");
}
}
usage
TheChecker checker = new ConcreteChecker();
checker.sayHello();
// not a functional, because it has 2 abstract methods in total
public interface TheChild extends TheChecker {
int bla();
}
void accept(T t)
default Consumer<T> andThen(Consumer<? super T> after)
long count = Arrays.stream(strings)
.map(String::length)
.count();
int totalLength = Arrays.stream(strings)
.mapToInt(String::length)
.sum();
OptionalDouble ave = Arrays.stream(strings)
.mapToInt(String::length)
.average();
OptionalInt max = Arrays.stream(strings)
.mapToInt(String::length)
.max();
OptionalInt reduce(IntBinaryOperator op)
int reduce(int identity, IntBinaryOperator op)
int sum = IntStream.rangeClosed(1, 10)
.reduce((x, y) -> x + y)
.orElse(0);
// x - accumulator, y - value of the element in stream
int sum = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.reduce(0, Integer::sum);
Stream.of("this", "is", "a", "list")
.reduce("", String::concat); // thisisalist
Stream.of("this", "is", "a", "list")
.collect(Collectors.joining());
<U> U reduce(U identity,
BiFunction<U,? super T,U> accumulator,
BinaryOperator<U> combiner)
public class Book {
private Integer id;
private String title;
}
books.stream()
.reduce(new HashMap<Integer,Book>(), // collect to
(map, book) -> { // how to add one element
map.put(book.getId(), book);
return map:
},
(map1, map2) -> { // how to compibe two maps. Needed for multithreading
map1.putAll(map2);
return map1;
});
Stream<T> peek(Consumer<? super T> action)
String implements CharSequence, it means
public default IntStream chars() {...}
public default IntStream codePoints() {...}