我有一个问题,我确信解决方案很简单,但我无法找到它。我有一个较小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
感谢任何帮助。谢谢
答案 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);
由于result
是LinkedHashSet
,它会保留插入顺序,因此元素的顺序将与内部列表中的顺序相同。
您还可以使用等效的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);
}
}