Java 8 函数式编程(4)

本篇对应《Java 8 函数式编程》第 5 章。


要点回顾

  1. 方法 引用 是一 种 引用 方法 的 轻量级 语法, 形如: ClassName:: methodName。
  2. 收集 器 可用 来 计算 流的 最 终值, 是 reduce 方法 的 模拟。
  3. Java 8 提供 了 收集 多种 容器 类型 的 方式, 同时 允许 用户 自定义 收集器。

练习

Question 1:

https://leetcode.com/playground/KrzQMGgR

public static void subquestionA() {
        List<String> collected = Stream.of("a", "b", "hello")
                                       .map(String::toUpperCase)
                                       .collect(Collectors.toList());
        System.out.println(collected);
    }
    
    public static void subquestionB() {
        int count = Stream.of(1, 2, 3)
                          .reduce(0, Integer::sum);
        System.out.println(count);
    }
    
    public static void subquestionC() {
        List<Integer> together = Stream.of(Arrays.asList(1,2), Arrays.asList(3,4))
                                       .flatMap(List::stream)
                                       .collect(Collectors.toList());
        System.out.println(together);
    }

Question 2:

LongestName.java

public class LongestName {

    private static Comparator<Artist> byNameLength = comparing(artist -> artist.getName().length());

    public static Artist byReduce(List<Artist> artists) {
        return artists.stream()
                      .reduce((acc, artist) -> {
                          return (byNameLength.compare(acc, artist) >= 0) ? acc : artist;
                      })
                      .orElseThrow(RuntimeException::new);
    }

    public static Artist byCollecting(List<Artist> artists) {
        return artists.stream()
                      .collect(Collectors.maxBy(byNameLength))
                      .orElseThrow(RuntimeException::new);
    }

}

WordCount.java

public class WordCount {

    public static Map<String, Long> countWords(Stream<String> names) {
        return names.collect(groupingBy(name -> name, counting()));
    }

}

GroupingBy.java

public class GroupingBy<T, K> implements Collector<T, Map<K, List<T>>, Map<K, List<T>>> {

    private final static Set<Characteristics> characteristics = new HashSet<>();
    static {
        characteristics.add(Characteristics.IDENTITY_FINISH);
    }

    private final Function<? super T, ? extends K> classifier;

    public GroupingBy(Function<? super T, ? extends K> classifier) {
        this.classifier = classifier;
    }

    @Override
    public Supplier<Map<K, List<T>>> supplier() {
        return HashMap::new;
    }

    @Override
    public BiConsumer<Map<K, List<T>>, T> accumulator() {
        return (map, element) -> {
            K key = classifier.apply(element);
            List<T> elements = map.computeIfAbsent(key, k -> new ArrayList<>());
            elements.add(element);
        };
    }

    @Override
    public BinaryOperator<Map<K, List<T>>> combiner() {
        return (left, right) -> {
            right.forEach((key, value) -> {
                left.merge(key, value, (leftValue, rightValue) -> {
                    leftValue.addAll(rightValue);
                    return leftValue;
                });
            });
            return left;
        };
    }

    @Override
    public Function<Map<K, List<T>>, Map<K, List<T>>> finisher() {
        return map -> map;
    }

    @Override
    public Set<Characteristics> characteristics() {
        return characteristics;
    }

}

Question 3:

Fibonacci.java

public class Fibonacci {

    private final Map<Integer,Long> cache;

    public Fibonacci() {
        cache = new HashMap<>();
        cache.put(0, 0L);
        cache.put(1, 1L);
    }

    public long fibonacci(int x) {
        return cache.computeIfAbsent(x, n -> fibonacci(n-1) + fibonacci(n-2));
    }

}

参考:

72 total views, 1 views today

Leave a Reply

Your email address will not be published. Required fields are marked *