【问题标题】:Sort list content to new lists将列表内容排序到新列表
【发布时间】:2018-10-13 01:58:15
【问题描述】:

我有一个未排序的列表,其中包含未知数量的项目,范围为 1000。这些项目都包含一个标签,用于确定它应该去哪里。为了避免多次迭代列表中的每个项目,我想将此列表拆分为一定数量的子列表,这些子列表仅包含某些标签的项目。

List<Item> allItems = getItemsFromSomewhere();

List<Item> itemsLabeledA1 = new ArrayList<>();
List<Item> itemsLabeledA2 = new ArrayList<>();
List<Item> itemsLabeledB1 = new ArrayList<>();
...
List<Item> itemsLabeledL3 = new ArrayList<>();

为了使问题进一步复杂化,一些列表需要添加范围的项目,这就是为什么每个项目都被标记为“A1”、“A2”、“A3”之类的东西。这些列表要求每个 项都添加一个 A 标签。但是,并非所有标签都有这些汇总列表。我可能必须聚合所有标记为 A 的项目,而不是聚合所有标记为 B 的项目,同时仍然在自己的列表中对 A1、B1 等进行排序。

鉴于上面的示例,我如何在一次迭代中优雅地拆分完整列表?我最初的想法是使用 ifs 或 switch 块,但这是一个丑陋的解决方案。

allItems.forEach(item -> {
    if (item.getLabel().contains("A1")) { 
       itemsLabeledA1.add(item);
       allItemsLabeledA.add(item);
    }
    else if (item.getLabel().contains("B1")) itemsLabeledB1.add(item);
    ...
    else if (item.getLabel().contains("L3")) itemsLabeledL3.add(item);
});

有没有更好的办法?

【问题讨论】:

  • 您可以使用标签作为键创建字典并以这种方式添加项目吗?这样你就不需要任何 if 语句或 switch 逻辑

标签: java sorting arraylist


【解决方案1】:

我会在两个单独的流操作中使用groupingBy:

Map<String, List<Item>> allByLabel = allItems.stream().collect(
    Collectors.groupingBy(Item::getLabel));

Map<String, List<Item>> allByLabelStart = allItems.stream().collect(
    Collectors.groupingBy(item -> item.getLabel().substring(0, 1)));

【讨论】:

    【解决方案2】:

    也许您可以尝试使用HashMap,其中键是标签,值是子列表?

    HashMap<String, List<Item>> map = new HashMap<String, List<Item>>();
    for (String label : labels) {
        map.put(label, new List<Item>);
    }
    allItems.forEach(item -> {
        String label = item.getLabel();
        map.get(label).add(item);
    }
    

    【讨论】:

    • 我不会在开始时制作标签,我会做一个 if 检查是否已经存在带有该标签的列表,否则创建一个。
    【解决方案3】:

    您似乎正在分类您的物品。为此,您需要根据您的规范创建不同的组,然后将每个项目添加到其组中。如果我正确理解您的要求,您可以按如下方式完成:

    Map<String, List<Item>> map = new LinkedHashMap<>(); // keeps insertion order
    allItems.forEach(it -> {
        String lbl = it.getLabel();
        map.computeIfAbsent(lbl, k -> new ArrayList<>()).add(it);
        if (needsToBeAggregated(lbl)) {
            map.computeIfAbsent(lbl.substring(0, 1), k -> new ArrayList<>()).add(it);
        }
    });
    

    boolean needsToBeAggregated(String label) 是您决定是否应将项目添加到聚合组的某种方法。

    此解决方案不使用流,而是使用 Java 8 的 Map.computeIfAbsent 方法。

    【讨论】:

      猜你喜欢
      • 2015-12-24
      • 2015-08-12
      • 1970-01-01
      • 2013-10-26
      • 1970-01-01
      • 2012-12-28
      • 2015-09-16
      • 1970-01-01
      • 2013-11-20
      相关资源
      最近更新 更多