如何检测 ArrayList 和 return 具有重复元素的新列表中的重复项
How to detect duplicates in ArrayList and return new List with duplicated elements
示例:
您收到一个包含以下内容的 ArrayList:“A,B,A,B,C,A,F,Z,C,H”
新的输出列表应该只包含重复的元素:“A,B,C”
您可以使用 set
集合来识别重复项,因为集合是不同元素的未排序列表。如果 Set 的 add()
方法 returns false
表示元素已经存在于列表中。
public static void main(String args[]) {
ArrayList<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("A");
list.add("B");
list.add("C");
list.add("A");
list.add("F");
list.add("Z");
list.add("C");
list.add("H");
Set<String> set = new HashSet<>();
Set<String> duplicateElements = new HashSet<>();
for (String element : list) {
if (!set.add(element)) {
duplicateElements.add(element);
}
}
System.out.println("Duplicate Elements : " + duplicateElements);
}
您可以使用频率散列映射来跟踪计数,并使用该映射过滤掉重复项
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("A");
list.add("B");
list.add("C");
list.add("A");
list.add("F");
list.add("Z");
list.add("C");
list.add("H");
Map<String, Integer> freqMap = new HashMap<>();
for (String s: list) {
if(freqMap.containsKey(s)){
freqMap.put(s, freqMap.get(s)+1);
} else {
freqMap.put(s, 1);
}
}
List<String> result = new ArrayList<>();
for(Map.Entry<String, Integer> entry: freqMap.entrySet()){
if(entry.getValue() > 1){
result.add(entry.getKey());
}
}
tl;博士
Set.copyOf( list ).stream().filter( s -> list.indexOf( s ) != list.lastIndexOf( s ) ).sorted().toList()
或者,重新格式化:
Set
.copyOf(
list // List.of( "A,B,A,B,C,A,F,Z,C,H".split( "," ) )
)
.stream()
.filter(
s -> list.indexOf( s ) != list.lastIndexOf( s )
)
.sorted()
.toList()
[A, B, C]
详情
根据您输入的字符串创建一个列表。使用 String#split
生成零件数组。将该数组提供给 List.of
会生成一个不可修改的 List
对象。
List < String > list = List.of( "A,B,A,B,C,A,F,Z,C,H".split( "," ) );
接下来,我们需要一个不同的字母集合,消除重复项。 Set
根据定义没有重复项。将我们的 List
传递给 Set.copyOf
会产生一个不可修改的 Set
对象。
Set < String > distinct = Set.copyOf( list );
我们要检查不同集合中的每个值,看看是否在原始列表中不止一次。
我们知道每个元素至少出现在列表中一次。所以我们可以使用 List#indexOf
来获取列表中的索引(从零开始的位置)。而我们可以得到List#lastIndexOf
来得到最后一个重复的位置。如果两次呼叫 return 相同的 号码,我们知道只有一次。如果两次调用return不同索引号,我们就知道我们有不止一个。因此,我们进行谓词测试,比较每个 String
元素的这两个调用:s -> list.indexOf( s ) != list.lastIndexOf( s )
.
我们可以使用流而不是写循环。我们调用 Set#stream
来生成不同集合元素的流。
我们过滤流中找到的第一个和最后一个索引不同的元素,同时忽略那些未通过谓词测试的元素。对于那些通过谓词测试的,首先我们排序,然后收集到 List
.
List < String > dups =
distinct
.stream()
.filter( s -> list.indexOf( s ) != list.lastIndexOf( s ) )
.sorted()
.toList(); // Before Java 16, replace with `.collect( Collectors.toList() );`.
list = [A, B, A, B, C, A, F, Z, C, H]
distinct = [A, H, F, Z, C, B]
dups = [A, B, C]
function dup(array) {
var tab = array[0].split(",");
var obj = {};
var result = [];
for (var i = 0; i < tab.length; i++) {
if (!obj[tab[i]]) {
obj[tab[i]] = 1;
} else {
obj[tab[i]]++;
}
}
for (var key in obj) {
if (obj[key] > 1) {
result.push(key);
}
}
return result;
}
只是为了提供一个替代方案,您可以使用流实现相同的算法:
list.stream()
.collect(Collectors.groupingBy(v -> v, Collectors.counting())
.entrySet().stream().filter(e -> e.getValue() > 1)
.map(e -> e.getKey())
.toList();
示例:
您收到一个包含以下内容的 ArrayList:“A,B,A,B,C,A,F,Z,C,H”
新的输出列表应该只包含重复的元素:“A,B,C”
您可以使用 set
集合来识别重复项,因为集合是不同元素的未排序列表。如果 Set 的 add()
方法 returns false
表示元素已经存在于列表中。
public static void main(String args[]) {
ArrayList<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("A");
list.add("B");
list.add("C");
list.add("A");
list.add("F");
list.add("Z");
list.add("C");
list.add("H");
Set<String> set = new HashSet<>();
Set<String> duplicateElements = new HashSet<>();
for (String element : list) {
if (!set.add(element)) {
duplicateElements.add(element);
}
}
System.out.println("Duplicate Elements : " + duplicateElements);
}
您可以使用频率散列映射来跟踪计数,并使用该映射过滤掉重复项
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("A");
list.add("B");
list.add("C");
list.add("A");
list.add("F");
list.add("Z");
list.add("C");
list.add("H");
Map<String, Integer> freqMap = new HashMap<>();
for (String s: list) {
if(freqMap.containsKey(s)){
freqMap.put(s, freqMap.get(s)+1);
} else {
freqMap.put(s, 1);
}
}
List<String> result = new ArrayList<>();
for(Map.Entry<String, Integer> entry: freqMap.entrySet()){
if(entry.getValue() > 1){
result.add(entry.getKey());
}
}
tl;博士
Set.copyOf( list ).stream().filter( s -> list.indexOf( s ) != list.lastIndexOf( s ) ).sorted().toList()
或者,重新格式化:
Set
.copyOf(
list // List.of( "A,B,A,B,C,A,F,Z,C,H".split( "," ) )
)
.stream()
.filter(
s -> list.indexOf( s ) != list.lastIndexOf( s )
)
.sorted()
.toList()
[A, B, C]
详情
根据您输入的字符串创建一个列表。使用 String#split
生成零件数组。将该数组提供给 List.of
会生成一个不可修改的 List
对象。
List < String > list = List.of( "A,B,A,B,C,A,F,Z,C,H".split( "," ) );
接下来,我们需要一个不同的字母集合,消除重复项。 Set
根据定义没有重复项。将我们的 List
传递给 Set.copyOf
会产生一个不可修改的 Set
对象。
Set < String > distinct = Set.copyOf( list );
我们要检查不同集合中的每个值,看看是否在原始列表中不止一次。
我们知道每个元素至少出现在列表中一次。所以我们可以使用 List#indexOf
来获取列表中的索引(从零开始的位置)。而我们可以得到List#lastIndexOf
来得到最后一个重复的位置。如果两次呼叫 return 相同的 号码,我们知道只有一次。如果两次调用return不同索引号,我们就知道我们有不止一个。因此,我们进行谓词测试,比较每个 String
元素的这两个调用:s -> list.indexOf( s ) != list.lastIndexOf( s )
.
我们可以使用流而不是写循环。我们调用 Set#stream
来生成不同集合元素的流。
我们过滤流中找到的第一个和最后一个索引不同的元素,同时忽略那些未通过谓词测试的元素。对于那些通过谓词测试的,首先我们排序,然后收集到 List
.
List < String > dups =
distinct
.stream()
.filter( s -> list.indexOf( s ) != list.lastIndexOf( s ) )
.sorted()
.toList(); // Before Java 16, replace with `.collect( Collectors.toList() );`.
list = [A, B, A, B, C, A, F, Z, C, H]
distinct = [A, H, F, Z, C, B]
dups = [A, B, C]
function dup(array) {
var tab = array[0].split(",");
var obj = {};
var result = [];
for (var i = 0; i < tab.length; i++) {
if (!obj[tab[i]]) {
obj[tab[i]] = 1;
} else {
obj[tab[i]]++;
}
}
for (var key in obj) {
if (obj[key] > 1) {
result.push(key);
}
}
return result;
}
只是为了提供一个替代方案,您可以使用流实现相同的算法:
list.stream()
.collect(Collectors.groupingBy(v -> v, Collectors.counting())
.entrySet().stream().filter(e -> e.getValue() > 1)
.map(e -> e.getKey())
.toList();