从ArrayLists的ArrayList中删除重复项

时间:2017-12-15 17:16:18

标签: java arraylist duplicates

我有一个问题,我确信解决方案很简单,但我无法找到它。我有一个较小ArrayList的{​​{1}}。这些列表包含ArrayList类型的元素。我想将较小的列表合并为一个,然后删除重复项。让我说清楚。

我有这个:

String

这是我的主要列表,其中包含较小的列表。我想要一个最终的[[USA, Maine], [USA, Maine, Kennebunk], [USA, Maine, North Berwick], [USA, New Hampshire], [USA, Keene, New Hampshire], [USA, Keene, New Hampshire, Main Street], [USA, New Hampshire, Swanzey]]. ,这是较小的合并,并删除重复项。

我想要的是:

ArrayList

感谢任何帮助。谢谢

6 个答案:

答案 0 :(得分:5)

这是使用Stream类的简明解决方案:

listOfLists.stream().flatMap(List::stream).collect(Collectors.toSet())

请注意,结果是Set类型。这样就可以删除重复项。

如果您需要List,可以使用:

listOfLists.stream()
           .flatMap(List::stream)
           .distinct()
           .collect(Collectors.toList())

请注意,这甚至可以保证元素的顺序稳定,即[["foo","bar"],["bar","abc","foo"]]将始终按此顺序生成["foo","bar","abc"]。使用Set的大多数解决方案都不能保证这一点,因为大多数解决方案都没有排序。

答案 1 :(得分:3)

使用Sets(Set不允许重复值)

的帮助很容易执行
public List<String> merge(List<List<String>> list) {
    Set<String> uniques = new HashSet<>();
    for(List<String> sublist : list) {
        uniques.addAll(sublist);
    }
    return new ArrayList<>(uniques);
}

P.S。当你想要你合并列表时,将排序将HashSet更改为TreeSet 像这样:Set<String> uniques = new TreeSet<>();

答案 2 :(得分:1)

传统解决方案:

Set<String> result = new LinkedHashSet<>();
for (List<String> innerList : filmingLocations) result.addAll(innerList);

由于resultLinkedHashSet,它会保留插入顺序,因此元素的顺序将与内部列表中的顺序相同。

您还可以使用等效的Java 8解决方案:

Set<String> result = new LinkedHashSet<>();
filmingLocations.forEach(result::addAll);

甚至是基于Java 8流的解决方案:

Set<String> result = filmingLocations.stream()
    .flatMap(List::stream)
    .collect(Collectors.toCollection(LinkedHashSet::new));

答案 3 :(得分:0)

如果您的目标是&lt; Java 8,您可以创建最终ArrayList的实例,让我们称之为“resultList”。然后迭代每个内部ArrayLists并仅添加Strings方法返回false的contains()。只有当您必须使用ArrayList作为最终收藏时,才能使用此解决方案。否则,您应该考虑使用HashSet,它会自动保留内部的唯一值并删除任何重复的对象。如果您需要使用ArrayList作为结果集合,以下代码可能对您有所帮助:

ArrayList<ArrayList<String>> sourceList = new ArrayList<>();
        // Adding sample ArrayLists ("a" and "b") of Strings to sourceList:
        ArrayList<String> a = new ArrayList<>();
        a.add("USA");
        a.add("Maine");
        sourceList.add(a);
        ArrayList<String> b = new ArrayList<>();
        b.add("USA");
        b.add("Maine");
        b.add("Kennebunk");
        sourceList.add(b);
        ArrayList<String> resultList = new ArrayList<>();
        for(ArrayList<String> outerList : sourceList) {
            for(String str : outerList) {
                // If resultList doesn't contain currently checked string...
                if(!(resultList.contains(str))) {
                    // Add this string to resultList...
                    resultList.add(str);
                }
            }
        }
        System.out.println(resultList.toString());

输出:[USA, Maine, Kennebunk]

答案 4 :(得分:0)

<强>解决方案:
在ArrayLists的ArrayList中循环使用String,如果使用ArrayList的.contains()方法将该字符串添加到此列表中,则将该字符串添加到另一个ArrayList

<强>代码:

  public ArrayList<String> merge(ArrayList<ArrayList<String>> startArrayList) {
    ArrayList<String> finalArrayList = new ArrayList<String>();
    //Iterate over each element
    for (ArrayList<String> innerList:startArrayList) {
      for (String value:innerList) {
        //add the String if it is missing
        if (!finalArrayList.contains(value))
          finalArrayList.add(value);
      }
    }
    return finalArrayList;
  }

答案 5 :(得分:0)

我看到这篇文章并且不得不回答,Berwick / Kennebunk是我住的城镇lol。你是当地人吗?

无论如何最简单的方法是使用上面提到的set操作。这有些O(log n)搜索。

public List<String> mergeTowns (List<List<String>> list) {
    Set<String> uniques = new HashSet<>();
    for(List<String> sublist : list) {
        uniques.addAll(sublist);
    }
    return new ArrayList<>(uniques);
}

如果您正在寻找更具动态性的数据结构,请使用一个地图,其中国家是您的关键,而城镇是您的价值观。这样,如果您决定建立一个由不同国家/地区建立城镇的大数据库,然后按国家/地区搜索地图以显示城镇。也许使用国家而不是国家作为你的关键。

结果数据结构将放弃这样的地图。打印时。

[USA = [berwick,kennebunk,north berwick,wells],CANADA = [berwick,kennebunk,north berwick,wells],MEXICO = [berwick,kennebunk,north berwick,wells]]

建立数据结构的方式可防止同一国家/地区的重复城镇条目。

public class Merge {


    private static ArrayList<String> mergeMap(HashMap<String, Set> map) {
        ArrayList<String> data = new ArrayList();
        for(Entry<String, Set> entries : map.entrySet()){
            String country = entries.getKey();
            Set<String> towns = entries.getValue();
            data.add(country+" = "+towns);
        }
        return data;
    }



    public static void main(String[] args) {
        //Mock data
        String[] countrys = {"USA", "CANADA", "MEXICO"};

        //Try this way of building your data structure instead of an array list of array list. 
        HashMap<String,Set> map = new HashMap<String,Set>();
        TreeSet<String> towns = new TreeSet<String>();

        // Add a couple towns to your set of towns
        towns.add("berwick");
        towns.add("north berwick");
        towns.add("kennebunk");
        towns.add("kennebunk");
        towns.add("kennebunk");
        towns.add("kennebunk");
        towns.add("wells");
        towns.add("wells");

        //With a map you could push a different set of towns to different countries
        for(String country: countrys){
            map.put(country, towns);
        }

        //Pass in your map<Country, Towns>
        ArrayList<String> mergedValues = mergeMap(map);
    }
}