2013-06-25 29 views
3

例如我的列表包含{4,6,6,7,7,8},并且我希望最终结果= {6,6,7,7}如何从java中的列表中选择重复值?

一种方法是循环遍历列表并消除唯一值(在这种情况下为4,8)。

是否有任何其他有效的方法,而不是通过列表循环?我问这个问题是因为我工作的列表非常大? 我的代码是

List<Long> duplicate = new ArrayList(); 
for (int i = 0; i < list.size(); i++) { 
    Long item = (Long) list.get(i); 
    if (!duplicate.contains(item)) { 
      duplicate.add(item); 
     } 
    } 
+0

您将通过整个列表必须循环,至少进行一次:

像这样的东西可以模拟多集。如果您必须比较列表中的每个值,才能更有效地解决列表创建问题,那么使用列表就没有“更高效”的方法。 –

+0

您至少需要一个循环。如果你想要一个更高效的代码(不是所有情况下都能保证),你可以尝试先排列列表,然后检查“邻居”是否不同(如果是,你有一个独特的项目,只需从列表中删除) – morgano

+0

如果你不想循环播放,你总是可以打印出列表并整理重复。 – Tdorno

回答

1

有一个

Map<Integer, Integer> numberToOccurance = new HashMap<Integer, Integer>(); 

维持数和数量,在最后迭代专用话机和一个以上的次数

+0

或者TreeMap如果你想要对数字进行排序。 – Puce

+0

为什么我们要排序的开销,散列更快! –

+0

好吧,只要OP想要对数字进行排序即可。在示例中,数字是排序的。 – Puce

-1

既然你可以通过循环做到这一点得到值通过列表只有一次,我不会担心表现太多。如果您搜索更高性能的解决方案,那么您最终可能会过度复杂化代码,并且可读性和可维护性将受到影响。在一天结束时,如果你想检查整个列表中的重复项,那么你必须访问每个元素。

我建议写明显的解决方案,看看它是如何执行的。您可能会惊讶Java可以在列表中迭代的速度,即使它特别大。

2
List<Number> inputList = Arrays.asList(4, 6, 6, 7, 7, 8); 
List<Number> result = new ArrayList<Number>(); 
for(Number num : inputList) { 
    if(Collections.frequency(inputList, num) > 1) { 
     result.add(num); 
    } 
} 

我不知道的效率,但我发现代码易于阅读(这应该是首选

编辑:改变Lists.newArrayList()new ArrayList<Number>();

+0

我想你在这里使用一些第三方库...('Lists.newArrayList()')?但是你可以使用'new ArrayList <>()'; – Puce

+0

哦,对,谢谢...它来自番石榴 –

+0

@Junaid我知道。我指的是'Lists.newArrayList()' – Puce

9

一些很好的答案,但迄今为止另一个选择只是为了它的乐趣循环列表试图将每个数字放入一个集合,例如HashSet如果add方法返回false,则您知道该数字是重复的并应该进入重复列表

编辑:这样的事情应该去做

Set<Number> unique = new HashSet<>(); 
List<Number> duplicates = new ArrayList<>(); 
for(Number n : inputList) { 
    if(!unique.add(n)) { 
     duplicates.add(n); 
    } 
} 
+0

由于输入数据是“大”,您应该预先分配集合的大小。 – johnstosh

5

是否有任何其他有效的方式,而不是通过列表循环?

你可以雇佣一个魔法小精灵,让它为你做。你怎么会想要做到这一点没有循环?如果你没有遍历列表,你甚至将无法查看元素。这就像你想把大量的数字汇总在一起而不看这些数字。求和元素比搜索重复元素或搜索独特元素要容易得多。一般来说,97%的代码是循环遍历列表和数据,并对其进行处理和更新。

所以,说,你必须循环。现在你可能想要选择最有效的方式。一些方法浮现在脑海中:

  • 排序所有数字,然后循环一遍以找到重复项(因为它们将彼此相邻)。但是,请记住排序算法也循环访问数据。
  • 对于列表中的每个元素,检查是否有另一个具有相同值的元素。 (这是你如何做到的。这意味着你有两个内部的循环。 (contains遍历进程的列表。))
-1

这里是我的版本的解决方案:

import java.util.ArrayList; 

public class Main { 

public static void main(String[] args) { 

    ArrayList<Integer> randomNumbers = new ArrayList<Integer>(); 
    ArrayList<Integer> expandingPlace = new ArrayList<Integer>(); 
    ArrayList<Integer> sequenceOfDuplicates = new ArrayList<Integer>(); 

    for (int i = 0; i < 100; i++) { 
     randomNumbers.add((int) (Math.random() * 10)); 
     expandingPlace.add(randomNumbers.get(i)); 
    } 

    System.out.println(randomNumbers); // Original list. 

    for (int i = 0; i < randomNumbers.size(); i++) { 
     if (expandingPlace.get(i) == expandingPlace.get(i + 1)) { 
      expandingPlace.add(0); 
      sequenceOfDuplicates.add(expandingPlace.get(i)); 
      sequenceOfDuplicates.add(expandingPlace.get(i + 1)); 
     } 
    } 

    System.out.println(sequenceOfDuplicates); // What was in duplicate there. 

} 

} 

它增加了从0到9的数字列表,并将其添加到另一个列表是什么在“重复”(一个数字后跟相同的数字)。你可以使用你的大列表而不是我的randomNumbers ArrayList。

+1

-1:该代码假定随机数被排序,而随机生成随机数不是这种情况。当没有重复时,此代码也会崩溃。这段代码也会报告一大堆重复。为了明白我的意思,在这些列表上测试这些代码:'3,1,3'(没有找到重复!)和'1,2,3'(崩溃!)和'1,1,1'(在重复列表中会报告四次'1'!)。 –

+0

你说得对。随机数只是我发现用随机信息填充列表的一种方式(给出了我不知道他的列表如何的事实)。 –

0

您的List理想情况下应该是Set,它首先不允许重复。作为一种替代循环,您既可以转换,切换到Set或者用它中间消除重复如下:

List<Long> dupesList = Arrays.asList(4L, 6L, 6L, 7L, 7L, 8L); 

Set<Long> noDupesSet = new HashSet<Long>(dupesList); 
System.out.println(noDupesSet); // prints: [4, 6, 7, 8] 

// To convert back to List 
Long[] noDupesArr = noDupesSet.toArray(new Long[noDupesSet.size()]); 
List<Long> noDupesList = Arrays.asList(noDupesArr); 
System.out.println(noDupesList); // prints: [4, 6, 7, 8] 
+0

这不回答这个问题,他希望所有重复的数字。在你的例子中是:[6,6,7,7] – karlihnos

0
import java.util.ArrayList; 
import java.util.HashSet; 
import java.util.List; 
import java.util.Set; 

public class FindDuplicate { 

    public static void main(String[] args) { 

     // Load all your ArrayList 
     List<String> list = new ArrayList<String>(); 
     list.add("Jhon"); 
     list.add("Jency"); 
     list.add("Mike"); 
     list.add("Dmitri"); 
     list.add("Mike"); 

     // Set will not allow duplicates 
     Set<String> checkDuplicates = new HashSet<String>(); 

     System.out.println("Actual list " + list); 
     for (int i = 0; i < list.size(); i++) { 
      String items = list.get(i); 
      if (!checkDuplicates.add(items)) { 
       // retain the item from set interface 
       System.out.println("Duplicate in that list " + items); 
      } 
     } 

    } 
} 
3

我想答案Java 8, Streams to find the duplicate elements。解决方案只返回唯一的重复项。

Integer[] numbers = new Integer[] { 1, 2, 1, 3, 4, 4 }; 
Set<Integer> allItems = new HashSet<>(); 
Set<Integer> duplicates = Arrays.stream(numbers) 
    .filter(n -> !allItems.add(n)) //Set.add() returns false if the item was already in the set. 
    .collect(Collectors.toSet()); 
System.out.println(duplicates); // [1, 4] 
+1

这并不回答问题,他希望所有重复的数字。在你的例子中是:[1,1,4,4] – karlihnos

0

随着番石榴和Java 8,这是微不足道的,快速:

Multiset<Integer> multiset = HashMultiset.create(list); 
return list.stream() 
    .filter(i -> multiset.count(i) > 1) 
    .collect(Collectors.toList()); 

第一行计算使用排序哈希地图的计数。其余部分比较明显。如果你想找到所有重复

HashMap<Integer, Integer> multiset = new HashMap<>(); 
list.stream().forEach(i -> 
    multiset.compute(i, (ignored, old) -> old==null ? 1 : old+1))); 
相关问题