【问题标题】:passing lambda as method arg and sorting map将 lambda 作为方法 arg 和排序映射传递
【发布时间】:2017-04-25 09:49:03
【问题描述】:


我必须创建使用映射参数和 lambda 表达式调用的排序方法。该方法返回作为第一个参数传递的任何映射的排序版本,排序顺序由作为第二个参数给出的 lambda 表达式确定。 我创建了类似的东西(不能正常工作):

public Map sorted(Map map, Function<Set> funct){


    System.out.println(map.entrySet()
       .stream()
       .sorted((Comparator) funct)
       .collect(Collectors.toList()));
     return null;
}

有什么想法吗?
感谢您的帮助;)

【问题讨论】:

  • 您应该将Comparator&lt;Map.Entry&lt;KeyType,ValueType&gt;&gt; 传递给sorted 方法。
  • Comparator 功能不同
  • 你“必须”?因为它对Map&lt;K,V&gt; sorted = new TreeMap&lt;&gt;(comparator); sorted.putAll(map); return sorted; 的可读性要高得多

标签: java sorting lambda functional-programming java-8


【解决方案1】:

如果您想要一个 排序的地图,它是 TreeMap,并且假设比较器按 Key 排序,它可能如下所示:

 public static <K, V> TreeMap<K, V> sorted(Map<K, V> map, Comparator<? super K> cmp) {

    return map.entrySet()
            .stream()
            .collect(Collectors.toMap(Map.Entry::getKey,     
                          Map.Entry::getValue, 
                          (left, right) -> left, 
                          () -> new TreeMap<K, V>(cmp)));

}

例如,它的调用如下所示:

 System.out.println(sorted(map, Comparator.naturalOrder()));

【讨论】:

  • 谢谢你的帮助,非常有用;)
【解决方案2】:

当我读到这个问题时,我在想一个更通用的解决方案,您可以在其中按键或值对地图进行排序。在这种情况下,解决方案如下所示:

public static <K,V> Map<K,V> sorted(Map<K,V> map, Comparator<Map.Entry<K, V>> comparator){
    return map.entrySet()
       .stream()
       .sorted(comparator)
       .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
}

如果要按值排序,可以这样使用:

sorted(yourMap, Entry.comparingByValue());

【讨论】:

  • 用法示例可以“缩短”为sorted(map, Comparator.comparing(Map.Entry::getValue))
  • 更短的sorted(map, Entry.comparingByValue())
  • 生活和学习,他们说! :) 实际上,我会直接在答案中使用适当的用法,而不是显示一些复杂的结构。
【解决方案3】:

如果您想将ToIntBiFunction 推荐给Comparator,您可以使用这个:

void sortByEntry() {
    Map<?, ?> map = new HashMap<>();
    Map<?, ?> sorted = sorted(map, this::comparingEntry);
}

<K, V> Map<K, V> sorted(Map<K, V> map, 
                        ToIntBiFunction<Entry<K, V>, Entry<K, V>> comparator) {
    return map.entrySet().stream()
            .sorted(comparator::applyAsInt)
            .collect(Collectors.toMap(Entry::getKey, Entry::getValue
                                    , (v1, v2) -> v2, LinkedHashMap::new));
}

<K, V> int comparingEntry(Entry<K, V> left, Entry<K, V> right) {
    return ...;
}

【讨论】:

  • Comparator@FunctionalInterface。因此无需将其替换为ToIntBiFunction。这样做会增加不存在的复杂性。这就是为什么我不赞成这个答案。如果我们删除该ToIntBiFunction,整个答案就会崩溃并退回到@Eugene 或@RobinTopper 的答案,从而使其重复。
  • @OlivierGrégoire 首先感谢您的评论。我知道Comparator 是一个功能接口,但我想告诉您如何在功能接口与 OP 之间进行选择。 RobinTopper 的答案是我的。
  • 你回答的意图还不是很清楚。您介意编辑您的答案以使其更加突出吗?这样我也可以撤回我的反对票(因为它在进一步编辑之前被锁定)。
  • @OlivierGrégoire 没关系,我不关心选票。但仍然再次感谢您的反馈。
猜你喜欢
  • 2019-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-11
  • 1970-01-01
  • 1970-01-01
  • 2012-12-27
相关资源
最近更新 更多