例如我的列表包含{4,6,6,7,7,8},我希望最终结果= {6,6,7,7}
一种方法是遍历列表并消除唯一值(在这种情况下为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 :(得分: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 );
}
}
答案 1 :(得分:5)
有没有其他有效的方法而不是循环列表?
你可以聘请一个魔法精灵让它为你做。你怎么会想要这样做而不循环呢?如果不循环遍历列表,您甚至无法查看元素。就像你想在不看这些数字的情况下将一大堆数字相加在一起。求和元素比搜索重复元素或搜索唯一元素容易得多。通常,97%的代码会循环遍历列表和数据并进行处理和更新。
所以说,你必须循环。现在您可能想要选择最有效的方式。我想到了一些方法:
contains
循环遍历当然的列表。))答案 2 :(得分:4)
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>();
答案 3 :(得分:4)
我喜欢回答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]
答案 4 :(得分:1)
有一个
Map<Integer, Integer> numberToOccurance = new HashMap<Integer, Integer>();
维护计数和数字,最后迭代键集并获取具有多个计数的值
答案 5 :(得分: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]
答案 6 :(得分: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);
}
}
}
}
答案 7 :(得分:0)
使用Guava和Java 8,它既简单又快速:
Multiset<Integer> multiset = HashMultiset.create(list);
return list.stream()
.filter(i -> multiset.count(i) > 1)
.collect(Collectors.toList());
第一行使用一种哈希映射计算计数。其余部分显而易见。
这样的东西可以模拟multiset:
HashMap<Integer, Integer> multiset = new HashMap<>();
list.stream().forEach(i ->
multiset.compute(i, (ignored, old) -> old==null ? 1 : old+1)));
答案 8 :(得分:0)
再次lambda节省了一天:
List<Long> duplicates = duplicate.stream()
.collect( Collectors.collectingAndThen( Collectors.groupingBy( Function.identity() ),
map -> {
map.values().removeIf( v -> v.size() < 2 ); // eliminate unique values (4, 8 in this case)
return( map.values().stream().flatMap( List::stream ).collect( Collectors.toList() ) );
} ) ); // [6, 6, 7, 7]
上述解决方案的速度优化版本:
List<Long> duplicates = duplicate.stream().collect( Collectors.collectingAndThen(
Collectors.groupingBy( Function.identity(), Collectors.counting() ),
map -> {
map.values().removeIf( v -> v < 2 ); // eliminate unique values (4, 8 in this case)
return( map.entrySet().stream().collect( Collector.of( ArrayList<Long>::new, (list, e) -> {
for( long n = 0; n < e.getValue(); n++ )
list.add( e.getKey() );
}, (l1, l2) -> null ) ) );
} ) ); // [6, 6, 7, 7]
duplicate
的长值不保存而是计数-无疑是最快,最节省空间的变体
答案 9 :(得分:0)
以下内容适用于Eclipse Collections:
IntBag bag = IntLists.mutable.with(4, 6, 6, 7, 7, 8).toBag().selectDuplicates();
如果要使用装箱值而不是基元,则可以使用以下方法:
Bag<Integer> bag = Lists.mutable.with(4, 6, 6, 7, 7, 8).toBag().selectDuplicates();
注意:我是Eclipse Collections的提交者。
答案 10 :(得分:0)
试试这个:
受到这个答案的启发:https://stackoverflow.com/a/41262509/11256849
for (String s : yourList){
if (indexOfNth(yourList, s, 2) != -1){
Log.d(TAG, s);
}
}
使用此方法:
public static <T> int indexOfNth(ArrayList list, T find, int nthOccurrence) {
if (list == null || list.isEmpty()) return -1;
int hitCount = 0;
for (int index = 0; index < list.size(); index++) {
if (list.get(index).equals(find)) {
hitCount++;
}
if (hitCount == nthOccurrence) return index;
}
return -1;
}
答案 11 :(得分:-1)
鉴于您可以通过循环列表只执行一次,我不会太担心性能。如果您搜索更高性能的解决方案,那么您可能最终会使代码过于复杂,可读性和可维护性将受到影响。在一天结束时,如果你想检查整个列表中的重复项,那么你必须访问每个元素。
我建议编写明显的解决方案,看看它的表现如何。你可能会惊讶于Java可以快速迭代列表,即使它特别大。
答案 12 :(得分:-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。