如何清除比较两个数组列表的重复项?
How to clear duplicates comparing two arraylists?
所以我有两个数组列表(这些只是作为示例)[Jeremy、Nick、Noah、Liam、Olivia] 和 [Elijah、Jeremy、Olivia、Sophia、Charlotte]。我将如何删除重复的“Jeremy”和“Olivia”,因为它们在第二个数组中。所以输出将是 firstArr: [Nick, Noah, Liam] 并且第二个 arraylist 将保持不变。这是我的方法,但不起作用。
public static ArrayList<String> removeDuplicates(ArrayList<String> firstArr, ArrayList<String> secArr) {
for (int i = 0; i < firstArr.size(); ++i) {
for (int p = 0; p < secArr.size(); ++p) {
if (firstArr.get(i).equals(secArr.get(p))) {
firstArr.remove(i);
p = secArr.size();
}
}
}
return firstArr;
}
解决方案非常简单,我只需要在删除元素后执行 i--
,因为所有内容都向左移动 1。
必须以这种方式进行提示,因为它是 class 的作业,我知道有更好的方法。
有很多方法可以做到这一点。但是,您需要记住的一件事是,如果您要修改它,您的循环不应该取决于集合大小;特别是如果您要删除元素。在遍历集合时修改集合的最佳方法是使用集合的 Iterator 对象并使用它来确定循环条件。例如,下面的代码等同于您要执行的操作:
public static void main(String[] args) {
List<String> firstArr = new ArrayList<>();
firstArr.add("Jeremy");
firstArr.add("Nick");
firstArr.add("Noah");
firstArr.add("Liam");
firstArr.add("Olivia");
List<String> secondArr = new ArrayList<>();
secondArr.add("Elijah");
secondArr.add("Jeremy");
secondArr.add("Olivia");
secondArr.add("Sophia");
secondArr.add("Charlotte");
Iterator<String> firstIter = firstArr.iterator();
while (firstIter.hasNext()) {
String elem = firstIter.next();
Iterator<String> secondIter = secondArr.iterator();
while (secondIter.hasNext()) {
String otherElem = secondIter.next(); // reacquire the iterator after each iteration.
if (elem.equals(otherElem)) {
firstIter.remove(); // safely removes the current item using Iterator#remove()
}
}
}
System.out.println(firstArr);
}
输出符合预期[Nick, Noah, Liam]
如您所见,循环条件不依赖于集合的大小;只有在检查的条件下才有更多的元素要检查。如果没有,它就简单地退出循环(或者不允许循环完全开始)。这是修改集合时推荐的迭代方式。
我并不是说这是解决这个特定问题的最佳方法,但它是解决此问题的一种方法,并且如果您在遍历集合时需要修改集合,则必须知道这一点。实际上。使用 Java 流可以最好地解决这个特定问题:
firstArr = firstArr.stream().distinct().filter(Predicate.not(secondArr::contains)).collect.(Collectors.toList));
这个表达式替换了整个嵌套循环结构。基本上,您想收集第一个列表中不在第二个列表中的成员。谓词被否定的原因是因为过滤器函数将 return 如果不否定匹配元素。
所以我有两个数组列表(这些只是作为示例)[Jeremy、Nick、Noah、Liam、Olivia] 和 [Elijah、Jeremy、Olivia、Sophia、Charlotte]。我将如何删除重复的“Jeremy”和“Olivia”,因为它们在第二个数组中。所以输出将是 firstArr: [Nick, Noah, Liam] 并且第二个 arraylist 将保持不变。这是我的方法,但不起作用。
public static ArrayList<String> removeDuplicates(ArrayList<String> firstArr, ArrayList<String> secArr) {
for (int i = 0; i < firstArr.size(); ++i) {
for (int p = 0; p < secArr.size(); ++p) {
if (firstArr.get(i).equals(secArr.get(p))) {
firstArr.remove(i);
p = secArr.size();
}
}
}
return firstArr;
}
解决方案非常简单,我只需要在删除元素后执行 i--
,因为所有内容都向左移动 1。
必须以这种方式进行提示,因为它是 class 的作业,我知道有更好的方法。
有很多方法可以做到这一点。但是,您需要记住的一件事是,如果您要修改它,您的循环不应该取决于集合大小;特别是如果您要删除元素。在遍历集合时修改集合的最佳方法是使用集合的 Iterator 对象并使用它来确定循环条件。例如,下面的代码等同于您要执行的操作:
public static void main(String[] args) {
List<String> firstArr = new ArrayList<>();
firstArr.add("Jeremy");
firstArr.add("Nick");
firstArr.add("Noah");
firstArr.add("Liam");
firstArr.add("Olivia");
List<String> secondArr = new ArrayList<>();
secondArr.add("Elijah");
secondArr.add("Jeremy");
secondArr.add("Olivia");
secondArr.add("Sophia");
secondArr.add("Charlotte");
Iterator<String> firstIter = firstArr.iterator();
while (firstIter.hasNext()) {
String elem = firstIter.next();
Iterator<String> secondIter = secondArr.iterator();
while (secondIter.hasNext()) {
String otherElem = secondIter.next(); // reacquire the iterator after each iteration.
if (elem.equals(otherElem)) {
firstIter.remove(); // safely removes the current item using Iterator#remove()
}
}
}
System.out.println(firstArr);
}
输出符合预期[Nick, Noah, Liam]
如您所见,循环条件不依赖于集合的大小;只有在检查的条件下才有更多的元素要检查。如果没有,它就简单地退出循环(或者不允许循环完全开始)。这是修改集合时推荐的迭代方式。
我并不是说这是解决这个特定问题的最佳方法,但它是解决此问题的一种方法,并且如果您在遍历集合时需要修改集合,则必须知道这一点。实际上。使用 Java 流可以最好地解决这个特定问题:
firstArr = firstArr.stream().distinct().filter(Predicate.not(secondArr::contains)).collect.(Collectors.toList));
这个表达式替换了整个嵌套循环结构。基本上,您想收集第一个列表中不在第二个列表中的成员。谓词被否定的原因是因为过滤器函数将 return 如果不否定匹配元素。