用流 Java 重写 SortedMap

Oan*_*ian 0 java collections java-stream

我有这个代码:

 SortedMap<String, Double> starsPerActivity = new TreeMap<>();
        for(Product p : products.values()) {
            for(Rating r : ratings) {
                if(r.getProductName() == p.getName()) {
                    starsPerActivity.put(p.getActivityName(), this.getStarsOfProduct(p.getName()));
                }
            }
        }
        return starsPerActivity;
Run Code Online (Sandbox Code Playgroud)

我想用流重写这段代码。我试过了,但我不知道如何。

方法starsPerActivity() 返回一个映射,该映射将活动名称与属于该活动的产品的平均星星数相关联,活动名称按字母顺序排序。产品未评级的活动不应出现在结果中。

Lin*_*ica 5

您可以使用第三个Collectors.toMap重载

public static <T, K, U, M extends Map<K, U>>
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
                         Function<? super T, ? extends U> valueMapper,
                         BinaryOperator<U> mergeFunction,
                         Supplier<M> mapFactory)
Run Code Online (Sandbox Code Playgroud)

这允许您定义要使用的地图实现:

SortedMap<String, Double> starsPerActivity = products.values().stream()
     .filter(p -> ratings.stream()
         .anyMatch(r -> r.getProductName().equals(p.getName())))
     .collect(Collectors.toMap(
         Product::getActivityName, 
         p -> getStarsOfProduct(p.getName()), 
         Double::max, TreeMap::new
     ));
Run Code Online (Sandbox Code Playgroud)

另外我注意到你r.getProductName() == p.getName()在你的if陈述中使用了,这可能适用于Strings. 不鼓励这样做,请参阅:如何比较 Java 中的字符串

请注意,此实现选择具有最高值的评级。您可以通过替换Double::max为您喜欢的逻辑来更改此行为。如果您想要与当前相同的行为,那么您可以使用它,它足够接近:(a, b) -> b它只是选择最新的看跌价值。