【问题标题】:Java 8 function that takes a List<V> and return a HashMap<K, List<V>>Java 8 函数接受 List<V> 并返回 HashMap<K, List<V>>
【发布时间】:2018-05-03 11:24:10
【问题描述】:

我正在尝试在 Java 8 中创建一个函数,该函数将列表作为参数并返回 HashMap 作为结果。

我已经在 J​​ava 7 中做到了,但我想通过使用 Java 8 流来做到这一点:

这是 Java 7 中的代码:

public static HashMap<String, List<Eleve>> getMentions(List<Eleve> liste){

    HashMap<String, List<Eleve>> listeMentions = new HashMap<String, List<Eleve>>();

    List<Eleve> noMention = new ArrayList<Eleve>();
    List<Eleve> mentionAB = new ArrayList<Eleve>();
    List<Eleve> mentionB  = new ArrayList<Eleve>();
    List<Eleve> mentionTB = new ArrayList<Eleve>();


    for (Eleve eleve: liste) {
        if (eleve.getAverage()>=12 && eleve.getAverage()<14) {mentionAB.add(eleve);}
        else if(eleve.getAverage()>=14 && eleve.getAverage()<16) {mentionB.add(eleve);}
        else if (eleve.getAverage()>=16) {mentionTB.add(eleve);}
        else{noMention.add(eleve);}
    }

    listeMentions.put("No mention", noMention);
    listeMentions.put("Mention AB", mentionAB); 
    listeMentions.put("Mention B",  mentionB);
    listeMentions.put("Mention TB", mentionTB);

    return listeMentions;
}

我尝试使用collect(Collectors.toMap) 流,但没有得到估计的结果。

【问题讨论】:

    标签: java lambda collections java-stream


    【解决方案1】:

    您可以创建一个接受int 平均值并返回该平均值对应的组的方法。

    public static String getGroup (int average) {
        if (average >= 12 && average < 14) {
            return "Mention AB";
        } else if(average >= 14 && average < 16) {
            return "Mention B";
        } else if (average >= 16) {
            return "Mention TB";
        } else {
            return "No mention";
        }
    }
    

    现在您可以使用Collectors.groupingBy 按此标准对您的实例进行分组:

    Map<String, List<Eleve>> listeMentions =
        liste.stream()
             .collect(Collectors.groupingBy(e -> getGroup(e.getAverage())));
    

    或者,您可以将Eleve 实例传递给getGroup() 方法,因此流管道将变为:

    Map<String, List<Eleve>> listeMentions =
        liste.stream()
             .collect(Collectors.groupingBy(e -> getGroup(e)));
    

    或者,如果您将getGroup() 设为Eleve 的实例方法(即public String getGroup() {...}):

    Map<String, List<Eleve>> listeMentions =
        liste.stream()
             .collect(Collectors.groupingBy(Eleve::getGroup));
    

    【讨论】:

    • 您还可以将第二个 sn-p 缩短为:从 e -&gt; getGroup(e)SomeClass::getGroup
    • @Lino 是的,我没有这样做,因为我没有决定哪个类将包含该方法:)
    • 这就是我想出一个假名的原因。只是想提一下,这也是可能的。但当然不适合你,你知道这是可能的 ;)
    【解决方案2】:

    非常感谢您的帮助。

    groupingBy 方法确实是解决方案。

    我没有创建一个函数,而是创建了一个 ENUM,然后将其用于我的 Steam,但它的工作方式相同。 代码如下:

    public enum Mention
    {
      BIEN, ASSEZ_BIEN,TRES_BIEN, BOF;
    
      public static Mention find(double average) {  
         if (average >= 12 && average < 14) {
                return ASSEZ_BIEN;
            } else if(average >= 14 && average < 16) {
                return BIEN;
            } else if (average >= 16) {
                return TRES_BIEN;
            } else {
                return BOF;
            }
    }
    

    }

    public static Map<Object, List<Eleve>> getMentions8(List<Eleve> liste){
                Map<Object, List<Eleve>> listeMentions =
                        liste.stream()
                             .collect(Collectors.groupingBy(e -> Mention.find(e.average)));
                return listeMentions;
            }
    

    【讨论】:

    • 为什么是Map&lt;Object, List&lt;Eleve&gt;&gt;?它应该是Map&lt;Mention, List&lt;Eleve&gt;&gt;。理想情况下,EnumMap,您应该使用接受地图供应商的Collectors.groupingBy 的重载版本。
    • 如果您对 Eran 的回答感到满意,请接受它以表扬他。
    猜你喜欢
    • 2020-04-08
    • 2013-12-20
    • 2019-01-23
    • 2014-02-09
    • 1970-01-01
    • 2017-05-20
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多