【问题标题】:Java: Using .stream to transform ArrayList<MyObj> to TreeMap<String, ArrayList<MyObj>>Java:使用 .stream 将 ArrayList<MyObj> 转换为 TreeMap<String, ArrayList<MyObj>>
【发布时间】:2015-11-05 18:37:36
【问题描述】:

这是一道 Java 8 中低级问题:

我在 Java 6 中有以下代码:

    List <ViewWrapperContentElementTypeProperty> vwPropertyList = getFromDao();


    TreeMap <Long, ArrayList<ViewWrapperContentElementTypeProperty>> mappedProperties = new TreeMap<Long, ArrayList<ViewWrapperContentElementTypeProperty>> ();
    for (ViewWrapperContentElementTypeProperty vwCetP:vwPropertyList)
    {
        if(null==mappedProperties.get(vwCetP.getContentElementTypeId()))
        {

            ArrayList<ViewWrapperContentElementTypeProperty> list = new ArrayList<ViewWrapperContentElementTypeProperty>());
            list.add(vwCetP);
            mappedProperties.put(vwCetP.getContentElementTypeId(), list);
        }
        else
        {
            mappedProperties.get(vwCetP.getContentElementTypeId()).add(vwCetP);
        }

    }

我可以使用 vwPropertyList.stream().map() 更有效地实现这一点吗?

【问题讨论】:

    标签: collections lambda java-8


    【解决方案1】:

    您似乎正在寻找按操作分组。幸运的是,Collectors 类提供了一种方法来做到这一点:

    import static java.util.stream.Collectors.groupingBy;
    import static java.util.stream.Collectors.toCollection;    
    
    ...
    
    TreeMap<Long, ArrayList<ViewWrapperContentElementTypeProperty>> mappedProperties =
                        vwPropertyList.stream()
                                      .collect(groupingBy(ViewWrapperContentElementTypeProperty::getContentElementTypeId, 
                                                          TreeMap::new,
                                                          toCollection(ArrayList::new)));
    

    我使用了groupingBy 的重载版本,您可以在其中提供特定的地图实现(如果您真的需要TreeMap)。

    toList() 收集器也返回一个List(这是一个ArrayList,但它是一个实现细节)。由于您显然需要指定一个具体的实现,因为您希望 ArrayLists 作为值,您可以使用 toCollection(ArrayList::new) 来完成。

    【讨论】:

      【解决方案2】:

      关于使用Streams 和 lambda 表达式,当然……这应该如下所示:

      Map<Long, List<ViewWrapperContentElementTypeProperty>> mappedProperties =
        vwPropertyList.stream()
            .collect(Collectors.groupingBy(ViewWrapperContentElementTypeProperty::getContentElementTypeId));
      

      请注意,使用上述 Stream API 方法会强制使用接口(@98​​7654323@、List),这无论如何都是一个好习惯。

      在性能方面,应该与使用传统循环大致相同。

      【讨论】:

      • 它不会强制您对接口进行编程。虽然在实践中很好,但您仍然有可能提供具体的实现 - 因为在某些情况下您可能明确需要具体的实现。
      • 确实...但是这种情况应该是例外,而不是规则。但是,如果 Jake 碰巧特别需要 TreeMap,例如,那么您是对的,他应该按照您的方式行事。
      • TreeMap 是首选,因为结果将直接显示在视图中并且需要顺序。节省了编写比较器并且对资源的需求很低,因为地图永远不会很大
      • @Jake:为什么它可以节省您编写比较器的时间?如果没有比较器的TreeMap 就足够了,那么没有比较器的排序也可以。仅当预期顺序与自然顺序不同(或不存在)时才需要比较器。但是,TreeMap 也需要一个比较器……
      • 我想我们可能误解了对方。我只是假设其他评论者对 TreeMap 的质疑是由于性能较慢。 TreeMap 保证自然键顺序(在我的情况下,按字母顺序排列)而 HashMap 不保证。这就是我选择 TreeMap 的原因。
      猜你喜欢
      • 2012-08-31
      • 2012-07-22
      • 1970-01-01
      • 2015-08-06
      • 2021-07-25
      相关资源
      最近更新 更多