Технологии Java
Лямбда-выражения и потоки
BiFunction<String, Long, String> f = (String s, Long v) -> { return s + v; }
BiFunction<String, Long, String> f = (String s, Long v) -> s + v;
BiFunction<String, Long, String> f = (s, v) -> s + v;
Function<String, String> f = s -> s + s;
Supplier<String> s = () -> "!";
Consumer<String> c = s -> System.out.println(s + s);
default <V> Function<V, R> compose(Function<−V, +T> before) { return v -> apply(before.apply(v)); }
default <V> Function<T, V> andThen(Function<−R, +V> after) { return v -> after.apply(apply(v)); }
Function<String, Integer> f1 = Integer::parseInt; // x -> Integer.parseInt(x);
Function<Integer, String> f2 = Integer::toString; // x -> x.toString();
Integer i = 2; // Не обязательно final Supplier<String> f3 = i::toString; // () -> i.toString();
Function<String, Integer> f4 = Integer::new; // s -> new Integer(s);
/* final */ String hello = "Hello, "; Function<String, String> greeter = name -> hello + name;
// Не работает, так как write бросает IOException Consumer<String> c = writer::write;
collection.forEach(e -> { if (e.equals("done")) { // Что делать? } });
@FunctionalInterface interface IOSupplier<T> { T get() throws IOException; static <T> T unchecked(IOSupplier<T> supplier) { try { return supplier.get(); } catch (IOException e) { throw new UncheckedIOException(e); } } }
List<String> lines = IOSupplier.unchecked(() -> Files.readAllLines(Path.of("input.txt")));
courses.sort( Comparator.comparingInt(Course::getYear) .thenComparingInt(Course::getTerm) .thenComparing( Course::getName, String.CASE_INSENSITIVE_ORDER ))
courses.forEach(System.out::println);
courses.removeIf(Course::isDone);
courses.toArray(Course[]::new);
courses.replaceAll(Course::nextYear);
Map<String, Integer> map = new HashMap<>(); while (scanner.hasNext()) { map.merge(scanner.next(), 1, Integer::sum); }
Map<String, Integer> map = new HashMap<>(); Files.readAllLines(input).forEach(line -> { for (String word : line.split("\\s+")) { map.merge(word, 1, Integer::sum); } });
string.stream() .filter(s -> s.endsWith("s")) .mapToInt(String::length) .min();
string.parallelStream() .filter(s -> s.contains("a")) .sorted(String.CASE_INSENSITIVE_ORDER) .limit(3) .collect(Collectors.joining(", "));
Map<String, Long> map = words.stream() .collect(Collectors.groupingBy( String::toUpperCase, Collectors.counting() ));
Map<String, Long> map = Files.lines(path) .flatMap(line -> Arrays.stream(line.split("\\s+")) .collect(Collectors.groupingBy( String::toUpperCase, Collectors.counting() ));
words.stream() .collect(Collectors.joining(", ", "{", "}"));
public boolean tryAdvance( Consumer<? super Entry<K, V>> action ) { checkForComodification(); if (i < bound) { action.accept(entry(i += 2)); return true; } return false; }
public Spliterator<Entry<K, V>> trySplit() { checkForComodification(); final int left = i; final int mid = (left + bound) / 4 * 2; if (i < mid) { i = mid; return new Spliter(left, mid); } return null; }
// [[a, b, c], [d]] chunked(List.of("a", "b", "c", "d", 3))
Stream<List<T>> chunked(Stream<+T> stream, int n) { Spliterator<+T> spliterator = stream.spliterator(); return StreamSupport.stream( new Spliterators.AbstractSpliterator<>( (spliterator.estimateSize() + n - 1) / n, spliterator.characteristics() & ~Spliterator.SORTED | Spliterator.NONNULL ) ); }
boolean tryAdvance(Consumer<-List<T>> action) { final List<T> chunk = new ArrayList<>(); while (chunk.size() < n && spliterator.tryAdvance(chunk::add)) { } if (!chunk.isEmpty()) { action.accept(chunk); } return !chunk.isEmpty(); }
<T> Collector<T, ?, Boolean> has(Predicate<-T> p) { class State { boolean found; } return Collector.of( State::new, (state, e) -> state.found |= p.test(e), (state1, state2) -> { state1.found |= state2.found; return state1; }, state -> state.found ); }
Collector<Student, String[], Student> MIN_NAMES = Collector.of( () -> new String[2], (mins, student) -> { mins[0] = min(mins[0], student.getFirstName()); mins[1] = min(mins[1], student.getLastName()); }, (mins1, mins2) -> { mins1[0] = min(mins1[0], mins2[0]); mins1[1] = min(mins1[1], mins2[1]); return mins1; }, mins -> new Student(mins[0], mins[1]) );
<T, F, S, FA, SA> Collector<T, Pair<FA, SA>, Pair<F, S>> tee( Collector<T, FA, F> c1, Collector<T, SA, S> c2 ) { return Collector.of( () -> new Pair<>( // supplier c1.supplier().get(), c2.supplier().get() ), (state, value) -> { // accumulator c1.accumulator().accept(state.v1, value); c2.accumulator().accept(state.v2, value); }, (state1, state2) -> new Pair<>( // combiner c1.combiner().apply(state1.v1, state2.v1), c2.combiner().apply(state1.v2, state2.v2) ), state -> new Pair<>( // finisher c1.finisher().apply(state.v1), c2.finisher().apply(state.v2) ) ); }
(state1, state2) -> new Pair<>( // combiner c1.combiner().apply(state1.v1, state2.v1), c2.combiner().apply(state1.v2, state2.v2) ), state -> new Pair<>( // finisher c1.finisher().apply(state.v1), c2.finisher().apply(state.v2) )
tee( Collectors.mapping(Student::firstName, Collectors.minBy(Comparator.naturalOrder())), Collectors.mapping(Student::lastName, Collectors.minBy(Comparator.naturalOrder())) )
teeing( mapping(Student::firstName, minBy(naturalOrder())), mapping(Student::lastName, minBy(naturalOrder())), (Optional<String> first, Optional<String> last) -> first.flatMap(f -> last.map(l -> new Student(f, l))) )