我的Java代码存在问题。我应该使用循环而不是任何其他方法。
假设我的ArrayLis
包含
[狗猫狗狗猫狗马]
我的目标也是删除狗和猫的副本,以便我的最终结果等于
[狗猫马]
public void removeDouble(){
int counter = 0;
for (int i = 0 ; i < animals.size(); i++) {
for (int j = 1+i; j < animals.size() ; j++)
//don't start on the same word or you'll eliminate it.
if ( animals.get(j).equals( animals.get(i) ) ) {
animals.remove(animals.get(j));
counter++;
}
}
}
感觉“逻辑”是正确的,但我的代码不能很好地工作。有人可以帮我一点吗?
答案 0 :(得分:2)
内循环的逻辑不正确。
每次在列表中连续出现相同的项目时,您都会跳过项目。
说你有&#34;狗&#34;,&#34;狗&#34;,&#34;狗&#34;,&#34;猫&#34;。当你删除&#34;狗&#34;在索引1处,列表现在变为&#34; dog&#34;,&#34; dog&#34;,&#34; cat&#34;。
问题是你的&#34; j&#34; index现在增加到2,因此下一个测试将访问&#34; cat&#34;项目,而不是&#34;狗&#34;项目。因此,每次删除项目时,您都会跳过列表中的下一项,这就是导致结果不一致的原因。
解决方案是:
答案 1 :(得分:2)
你可以这样做。
ArrayList<String>list=new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("A");
System.out.println("Before "+list); // output[A,B,C,A]
Set<String> listWithoutDuplicates = new LinkedHashSet<String>(list);
list.clear();
list.addAll(listWithoutDuplicates);
System.out.println("list without duplicates : " + list);// output[A,B,C]
答案 2 :(得分:1)
从列表末尾开始并递减计数器会更简单。在i处删除double之后,我们可以在不检查整个字符串的情况下中断,因为当我到达j时将检测到更多的双精度。
for(int i=animals.size()-1; i>0; i--) {
for(int j=i-1; j>=0; j--) {
if(animals.get(i).equals(animals.get(j))) {
animals.remove(i);
break;
}
}
}
向后移动可以避免出现问题,因为您在前进时索引已更改,因为您删除了之前的元素(并且您无法调整索引以将其考虑在内)。
您的逻辑使用remove(object)而不是remove(index)的另一个问题,这会导致第一个匹配对象被删除。但是,根据预期输出,您希望保留第一个匹配对象的顺序。所以你应该通过索引删除最后一个匹配的对象。
如果你想向前而不是向后移动,但你不想在删除后对索引进行调整,可以使用迭代器的remove方法:
for(int i=0; i<animals.size()-1; i++) {
ListIterator<?> iter = animals.listIterator(i+1);
while(iter.hasNext()) {
if(animals.get(i).equals(iter.next())) {
iter.remove();
}
}
}
不幸的是,这里的外部循环不能使用迭代器,因为这会导致ConcurrentModificationException。
最后,您还可以使用subList通过一个显式循环来解决它:
for(int i=0; i<animals.size()-1; i++) {
animals.subList(i+1, animals.size()).removeIf(animals.get(i)::equals);
}
答案 3 :(得分:1)
使用Java 8流,您可以执行以下操作:
public class RemoveDuplicates {
public static void main(String[] args) {
removeDuplicateElements(Arrays.asList("Dog","Cat","Dog","Dog","Cat","Dog","Horse"));
}
private static void removeDuplicateElements(List<String> animalList)
{
animalList.stream().distinct().collect(Collectors.toList()).forEach(System.out::println);
}
}
答案 4 :(得分:0)
您当前的代码 -
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="ip1" />
<input type="button" id="check_button" value="checking" />
<input type="button" id="write_button" value="write" />
<p id="store_value"></p>
一种简单的方法是
for (int i = 0; i < animals.size(); i++) {
for (int j = 1 + i; j < animals.size(); j++)
if (animals.get(j).equals(animals.get(i))) {
animals.remove(animals.get(j)); // this would remove the current element only if the previous element is same as the current element
// since the index `j` would change post that
}
}
}
或使用 -
animals.stream().distinct().collect(Collectors.toList()).forEach(System.out::print);
答案 5 :(得分:0)
在迭代它们时删除项目,有一个包含索引的数组,当你找到一个double时,将索引添加到索引数组。迭代索引数组并从动物arraylist中删除。
答案 6 :(得分:0)
感谢所有答案。我还有一些问题,这就是我想出的:
int counter =0;
for(int i = 0 ; i < animals.size() ; i++){
for(int j = animals.size() -1 ; j>i ; j--){
if(animals.get(j).equals(animals.get(i))){
counter++;
}
}
}
System.out.println(counter);
}
所以现在我从ArrayList的末尾开始内部循环。现在优先级只是获取循环工作然后添加删除等。
干杯!
答案 7 :(得分:0)
在Java 8中,我们可以使用Stream API删除重复项,就像下面的代码段一样。
List<String> uniqueAnimal = animal.stream().distinct().collect(Collectors.toList());
工作示例。
import java.util.*;
import java.util.stream.Collectors;
public class MyClass {
public static void main(String args[]) {
List<String> animal = new ArrayList<>();
animal.add("Dog");
animal.add("Cat");
animal.add("Dog");
animal.add("Dog");
animal.add("Cat");
animal.add("Dog");
animal.add("Horse");
List<String> uniqueAnimal = animal.stream().distinct().collect(Collectors.toList());
System.out.println("animal => " + animal);
System.out.println("uniqueAnimal => " + uniqueAnimal);
}
}