我有一个带有String键的HashMap和MyObject值的ArrayList,现在我想创建一个包含所有重叠MyObjects的列表的新列表。
例如:如果ArrayList1包含MyObjectA,MyObjectB,MyObjectC和ArrayList2包含MyObjectA,MyObjectD,MyObjectE,那么我想将MyObjectA-E添加到新列表中,并将所有这些列表放在主列表中。如果任何值重叠,我想基本上将每个ArrayList的值组合成一个新列表。
到目前为止,我只是遍历地图,遍历每个列表,然后再次嵌套迭代,如果有任何值匹配,则在嵌套中对两个ArrayLists执行另一次迭代,将它们添加到不同的列表中,但是这样导致新列表中的重复。
对不起,如果不是很清楚。
有没有人有任何建议或者更好的方法来实现这个目标?
谢谢!
这是我的代码:
public class DetermineOverlaps {
HashMap<String, ArrayList<CustomObject>> pgsPerStMap;
HashSet<HashSet<String>> competingPgs;
public DetermineOverlaps (HashMap<String, ArrayList<CustomObject>> pgsPerStMap2){
pgsPerStMap = new HashMap<String, ArrayList<CustomObject>>(pgsPerStMap2);
competingPgs = calculateCompetingPgs();
}
public HashSet<HashSet<String>> calculateCompetingPgs (){
//This will be the hashset which gets returned from this method
HashSet<HashSet<String>> competingProdGros = new HashSet<HashSet<String>>();
//I will iterate over each term (key) within the pgsPerStMap map, which contains search terms | all customObject for that search term
for (String searchTerm : pgsPerStMap.keySet()){
//I will iterate over each customObject for the search term
ArrayList<CustomObject> searchTermsPgs = pgsPerStMap.get(searchTerm);
for (CustomObject curProdGroup : searchTermsPgs){
String curProdGroupName = curProdGroup.key;
//I will store all found matches in this hashset, which I will later put in the competingProdGros map
HashSet<String> tempPgSet = new HashSet<String>();
//Compare every other key/value combination of the map to every other key/value combination of the map
for (String searchTerm2ndLevel : pgsPerStMap.keySet()){
//Iterate over the customObject
ArrayList<CustomObject> searchTermsPgsLev2 = pgsPerStMap.get(searchTerm2ndLevel);
for (CustomObject curProdGroup2ndLevel : searchTermsPgsLev2){
String curProdGroupLevel2Name = curProdGroup2ndLevel.key;
//If these are different keys, but the same value, i.e. you've got a value which has multiple
//overlapping keys, and the temporary hashset doesn't contain the value already
//Then add all values from both arraylist<CustomObject> into the temporary hashset...
if (!searchTerm2ndLevel.equals(searchTerm) && curProdGroupLevel2Name.equals(curProdGroupName)
&& !tempPgSet.contains(curProdGroupLevel2Name)){
for (CustomObject levelOnePg : searchTermsPgs){
String levelOnePgKey = levelOnePg.key;
tempPgSet.add(levelOnePgKey);
}
for (CustomObject levelTwoPg : searchTermsPgsLev2){
String levelTwoPgKey = levelTwoPg.key;
tempPgSet.add(levelTwoPgKey);
}
}
}
}
//Add the temporary hashset into the competingProdGros hashset
if(!competingProdGros.contains(tempPgSet)){competingProdGros.add(tempPgSet);}
}
}
//return the competingprodgros hashset
return competingProdGros;
}
答案 0 :(得分:1)
我无法做出你正在尝试做的事情的正面或反面,但我可以给你一些想法来帮助你实现它。
你说你想要一个A-E对象列表,所以我会说你不允许重复。在这种情况下,您可以使用String to Sets的映射来减少主列表的大小
我将给你4个场景:
场景1:您不允许重复,列表是对具有唯一内容的对象的引用
Map<String, Set<MyObject> map = new HashMap<String, Set<MyObject>>();
Set<MyObject> set1 = new LinkedHashSet<MyObject>();
Set<MyObject> set2 = new LinkedHashSet<MyObject>();
MyObject a = new MyObject("A");
MyObject b = new MyObject("B");
MyObject c = new MyObject("C");
MyObject d = new MyObject("D");
MyObject e = new MyObject("E");
set1.add(a);
set1.add(b);
set1.add(c);
set2.add(c);
set2.add(d);
set2.add(e);
set2.removeAll(set1)
set1.addAll(set2);
map.put("Mykey", set1);
这说的是对象在集合中是相同的,因此将在两个集合之间移除。 set1的内容是:
[ "A", "B", "C", "D", "E" ]
场景2:您允许重复,列表是对相同对象的引用。在这里,我猜你想要一对一的删除,所以你循环通过一组交叉点直到为空,然后将列表添加到组合列表中。如果您需要维护列表的值,您可以始终实例化一个新列表并将其传递给列表中的内容
最后一点注意事项:删除增强for循环中树集的元素会导致抛出ConcurrentModificationException
MyObject a = new MyObject("A");
MyObject b = new MyObject("B");
MyObject c = new MyObject("C");
MyObject d = new MyObject("D");
MyObject e = new MyObject("E");
List<CodeTester> l = new ArrayList<CodeTester>();
List<CodeTester> l2 = new ArrayList<CodeTester>();
l.add(a);
l.add(c);
l.add(c);
l.add(b);
l.add(b);
l.add(d);
l2.add(c);
l2.add(d);
l2.add(d);
l2.add(e);
Set<CodeTester> set = new HashSet<CodeTester>(l);
set.retainAll(l2); // get the intersections
while(!set.isEmpty()) {
l2.remove(0);
set.retainAll(l2);
}
map.put("myKey", set);
这些内容的输出是:
[ "A", "C", "C", "B", "B", "D", "D", "E" ]
注意&#34; C&#34;的一个实例和&#34; D&#34;被排除在最终名单之外,因为另一个名单有他们
场景3:您不允许重复,但不保证列表元素是对具有唯一内容的对象的引用
如果我不得不猜测我说这是你正在寻找的那个。 这里MyObject使用不同的哈希码/ id实例化新实例。这使得所有MyObject实例都是唯一的,无论内容如何,因此如果使用相同的String声明两个MyObject,则默认的Collections操作不会删除/保留它们。要比较内容,您需要实现一些重写方法。然后,您将能够以相同的方式使用上述过程。唯一不同的是用户TreeSet而不是HashSet来调用重写的equals方法然后我们可以实现Comparable或实现Comparator来使用TreeSet并避免它将从其默认的Comparator抛出的ClassCastException。
For Sets强制执行唯一性:
public class MyObject implements Comparable<MyObject>
String s;
Map<String, Set<MyObject> map = new HashMap<String, Set<MyObject>>();
Map<String, List<MyObject> map = new HashMap<String, List<MyObject>>();
public MyObject(String s){
this.s = s;
}
public void myExample1(){
Set<MyObject> set1 = new TreeSet<MyObject>();
Set<MyObject> set2 = new TreeSet<MyObject>();
MyObject a = new MyObject("A");
MyObject b = new MyObject("B");
MyObject c = new MyObject("C");
MyObject d = new MyObject("D");
MyObject e = new MyObject("E");
MyObject b2 = new MyObject(new StringBuilder("F").replace(0, 1, "B").toString());
MyObject d2 = new MyObject(new StringBuilder("G").replace(0, 1, "D").toString());
set1.add(a);
set1.add(b);
set1.add(c);
set2.add(b2);
set2.add(d);
set2.add(d2);
set2.add(e);
set2.removeAll(set1)
set1.addAll(set2);
mapS.put("Mykey", set1);
}
public void myExample2(){
List<MyObject> l = new ArrayList<MyObject>();
List<MyObject> l2 = new ArrayList<MyObject>();
l.add(a);
l.add(c);
l.add(c);
l.add(b2);
l.add(d);
l2.add(b);
l2.add(d);
l2.add(d2);
l2.add(e);
Set<MyObject> set = new TreeSet<MyObject>(l);
set.retainAll(l2); // get the intersections
Set<MyObject> set2 = new HashSet<MyObject>(set);
while(!set.isEmpty()) {
l2.remove(0);
set.retainAll(l2);
}
l.addAll(l2);
mapL.put("myKey", l);
}
@Override
public int compareTo(MyObject o){
return s.compareTo(o.getS);
}
public String getS(){
return s;
}
@Override
public boolean equals(Object o){
return o instanceof MyObject && compareTo((MyObject) o);
}
}
myExample1输出:
[ "A", "B", "C", "D", "E" ]
使用代码显示唯一性:
[A 865113938, B 1442407170, C 1028566121] [B 1118140819, D 1975012498, E 1808253012]
[A 865113938, B 1442407170, C 1028566121, D 1975012498, E 1808253012]
myExample1输出:
[ "A", "B", "C", "D", "E" ]
使用哈希码来显示唯一性:
[A 865113938, C 1442407170, C 1442407170, B 1028566121, D 1118140819] [B 1975012498, D 1118140819, D 1808253012, E 589431969]
[A 865113938, C 1442407170, C 1442407170, B 1028566121, D 1118140819, E 589431969]
答案 1 :(得分:0)
使用addAll()函数。 例如:ArrayList1.addAll(ArrayList2) 现在ArrayList1将包含所有没有重复的值