2012-12-05 53 views
1

我有对象的列表格式如下:如何创建重复列表项目的列表?

class myObj { 

    private String identifier; 

    public myObj(String identifier){ 
     this.identifier = identifier; 
    } 

} 

List<myObj> allobjects = new ArrayList<myObj>(); 
allobjects.add(new myObj("123")); 
allobjects.add(new myObj("123")); 
allobjects.add(new myObj("123")); 
allobjects.add(new myObj("123")); 
allobjects.add(new myObj("1234")); 
allobjects.add(new myObj("12345")); 
allobjects.add(new myObj("12")); 
allobjects.add(new myObj("12")); 

什么是提取重复的对象为单独列出的一个优雅的方法是什么? 所以在上面的例子中返回一个包含两个列表的新列表。所述第一列表 包含:

new myObj("123"); 
new myObj("123"); 
new myObj("123"); 
new myObj("123"); 

第二列表包含:

new myObj("12"); 
new myObj("12"); 

一种可能的解决方案是创建一个新对象:

List<List<myObj>> newList = new ArrayList<List<myObj>> 

,然后在列表中的每个元素'allobjects'遍历每个元素,并且对于包含多个元素的每个元素将其添加到列表中。然后在 当前元素的迭代结束时将新创建的列表添加到'newList'

这是可以接受的还是有其他解决方案吗?

+0

请问一个解决方案,独特的元素也得到了自己的名单会好吗? – durron597

+0

@ durron597我可以忽略列表项目的大小== 1 –

+1

使用自定义的“Comparator ”(或创建新列表并对其进行排序)对您的列表进行排序。浏览排序的列表并检测相邻的重复项。这样你的算法只能是* O(nlogn)*,而你提出的解决方案是* O(n²)*。 – brimborium

回答

2

添加equals和hashCode方法的MyObj中类,这样就可以将它们作为地图键:

class myObj { 

    private String identifier; 

    public myObj(String identifier){ 
     this.identifier = identifier; 
    } 

    public int hashCode(){ 
     return identifier.hashCode(); 
    } 

    public boolean equals(Object o){ 
     return identifier.equals(((myObj)o).identifier); 
    } 
} 

然后声明一个Map:

Map<myObj, List<myObj>> map = new HashMap<myObj, List<MyObj>>() 

,并通过迭代原始列表。使用myObjs作为映射键,每次检索与myObj相对应的列表。如果你遇到的第一次一定MyObj中,不要忘了创建列表:

for(myObj obj : allobjects){ 
    List<myObj> list = map.get(obj); 
    if(list == null){ 
     list = new ArrayList<myObj>(); 
     map.put(obj, list); 
    } 
    list.add(obj); 
} 
1

执行等于所需要的,然后你可以使用包含和迭代通过检查其他集合。

以下是使用jdk8s的lambda表达式的方法。

TransformService transformService = (inputs1, inputs2) -> { 
      Collection<String> results = new ArrayList<>(); 
      for (String str : inputs1) { 
       if (inputs2.contains(str)) { 
        results.add(str); 
       } 
      } 
      return results; 
     }; 
     Collection<String> inputs1 = new ArrayList<String>(2) {{ 
      add("lemon"); 
      add("cheese"); 
      add("orange"); 
     }}; 
     Collection<String> inputs2 = new 
       ArrayList<String>(2) {{ 
        add("apple"); 
        add("random"); 
        add("cheese"); 
       }}; 
     Collection<String> results = transformService.transform(inputs1, inputs2); 
     for (String result : results) { 
      System.out.println(result); 
     } 
    } 

    public interface TransformService { 
     Collection<String> transform(Collection<String> inputs1, Collection<String> inputs2); 
    } 
+0

我应该提到这需要与java6一起工作,所以没有lambda表达式:( –

+0

@ user470184以及答案仍然存在,只是通过列表循环,如果包含,添加到新列表.... – NimChimpsky