我试图从链表中删除所选数字的所有倍数,例如,删除2:的倍数
[0,12,16,0,13,9,13,17,5,12,1,12,5,5,1,6,14,12,14]->[13,9,13,17,5,5,5,5,1]
我写这段代码是为了构建一个由20个随机整数组成的链表,然后根据条件从中删除元素
import java.util.Scanner;
import java.util.*;
public class MyList {
public static void main(String args[])
{
int entero = 0;
Random random = new Random();
LinkedList<Integer> objectList = new LinkedList<Integer>();
Scanner scan = new Scanner(System.in);
for(int i=0; i<20; i++){
int randomInteger = random.nextInt(20);
objectList.add(randomInteger);
}
System.out.print("Enter a number between 1 y 5: ");
int intNumber = scan.nextInt();
if(intNumber > 5 || intNumber < 1){
}else{
System.out.println("List : " + objectList);
if(intNumber == 2){
for(int j=0; objectList.size()>j; j++){
System.out.println("va " + objectList.get(j));
if (objectList.get(j) % 2 == 0) {
objectList.remove(objectList.get(j));;
}
}
}
}
System.out.println("Final List : " + objectList);
}
}
这个问题是,它不会删除某些项目,即使它应该删除(例如:条件14%2==0被评估为真,但数字不会被删除(,所以结果是这样的:
从[0,12,16,0,13,9,13,17,5,12,1,12,5,5,1,6,14,12,14]->到[0,13,9,13,17,5,1,5,12,14,14]
为什么这没有从列表中删除所有2的倍数?
您正在删除列表元素,同时对其进行迭代。因此,例如,在删除索引为0的元素后,下一次迭代将指向objectList[1],该元素在删除objectList[0]之前是objectList[2]。调试时可以很容易地看到它。
例如,您可以创建一个要删除的元素列表,然后使用removeAll(toDelete(。
但对我来说,最好的方法是使用流api。
objectList.stream().filter(o -> o%2!=0).collect(Collectors.toList())
会准确地返回您需要的内容。
更新:我刚刚发现,有一个removeIf(Predicate<? super E> filter)
方法。
所以你可以简单地使用
l.removeIf(o -> o % 2 == 0);
享受;(
问题是在遍历列表时从列表中删除项目。这就是为什么它没有按照你想象的方式行事。
但是,您可以使用迭代器.remove((方法来解决您的问题。在这种情况下,您必须通过迭代器进行迭代。代码可能如下:
if(intNumber == 2){
Iterator<Integer> iter = objectList.iterator();
while (iter.hasNext()) {
if (iter.next() % 2 == 0) {
iter.remove();;
}
}
}
这应该能解决你的问题。如果你不理解任何部分,请告诉我。编码快乐!
问题是在遍历列表时从列表中删除项目。这就是为什么它没有按照你想象的方式行事
您正在删除列表元素,同时对其进行迭代。因此,例如,在删除索引为0的元素后,下一次迭代将指向objectList[1],它在删除objectList[0]之前是objectList[2]。调试时可以很容易地看到它。
导入java.util.Scanner;导入java.util.*;
public class MyList {
public static void main(String args[])
{
int entero = 0;
Random random = new Random();
LinkedList<Integer> objectList = new LinkedList<Integer>();
LinkedList<Integer> removeObjectList = new LinkedList<Integer>();
Scanner scan = new Scanner(System.in);
for(int i=0; i<20; i++){
int randomInteger = random.nextInt(20);
objectList.add(randomInteger);
}
System.out.print("Enter a number between 1 y 5: ");
int intNumber = scan.nextInt();
if(intNumber > 5 || intNumber < 1){
}else{
System.out.println("List : " + objectList);
if(intNumber == 2){
for(int j=0; objectList.size()>j; j++){
System.out.println("va " + objectList.get(j));
if (objectList.get(j) % 2 == 0) {
// objectList.remove(objectList.get(j));// do not remove element from here.
removeObjectList.add(objectList.get(j));
}
}
}
}
LinkedList<Integer> finalList = new LinkedList<>();
for(Integer num : objectList){
if(removeObjectList.stream().noneMatch(it -> it.equals(num))){
finalList.add(num);
}
}
System.out.println("Final List : " + objectList);
}
}
您未能说明每次删除元素时每个元素的索引都会发生变化。以下是您给出的同一测试用例的输出,除了一些用于跟踪列表状态的打印语句。这应该会让你的代码表现得更清楚:
Enter a number between 1 y 5: 2
List : [0, 12, 16, 0, 13, 17, 5, 12, 1, 12, 1, 12, 5, 5, 1, 6, 14, 12, 14, 14]
objectList.get(j)%2 = 0
Deleting 0
List : [12, 16, 0, 13, 17, 5, 12, 1, 12, 1, 12, 5, 5, 1, 6, 14, 12, 14, 14]
objectList.get(j)%2 = 0
Deleting 16
List : [12, 0, 13, 17, 5, 12, 1, 12, 1, 12, 5, 5, 1, 6, 14, 12, 14, 14]
objectList.get(j)%2 = 1
objectList.get(j)%2 = 1
objectList.get(j)%2 = 1
objectList.get(j)%2 = 0
Deleting 12
List : [0, 13, 17, 5, 12, 1, 12, 1, 12, 5, 5, 1, 6, 14, 12, 14, 14]
objectList.get(j)%2 = 0
Deleting 12
List : [0, 13, 17, 5, 1, 12, 1, 12, 5, 5, 1, 6, 14, 12, 14, 14]
objectList.get(j)%2 = 0
Deleting 12
List : [0, 13, 17, 5, 1, 1, 12, 5, 5, 1, 6, 14, 12, 14, 14]
objectList.get(j)%2 = 1
objectList.get(j)%2 = 1
objectList.get(j)%2 = 0
Deleting 6
List : [0, 13, 17, 5, 1, 1, 12, 5, 5, 1, 14, 12, 14, 14]
objectList.get(j)%2 = 0
Deleting 12
List : [0, 13, 17, 5, 1, 1, 5, 5, 1, 14, 12, 14, 14]
objectList.get(j)%2 = 0
Deleting 14
List : [0, 13, 17, 5, 1, 1, 5, 5, 1, 12, 14, 14]
Final List : [0, 13, 17, 5, 1, 1, 5, 5, 1, 12, 14, 14]
这是因为在删除列表的当前位置时,您在列表上正向迭代,因此您跳过了几个元素。
如果你把for循环改为负方向,你的代码就会工作:
for(int j=objectList.size((-1;0
因此,最终的解决方案可能看起来像(代码略有改进(:
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
public class MyList {
public static void main(String args[]) {
int entero = 0;
Random random = new Random();
ArrayList<Integer> integerList = new ArrayList<Integer>();
Scanner scan = new Scanner(System.in);
for (int i = 0; i < 20; i++) {
int randomInteger = random.nextInt(20);
integerList.add(randomInteger);
}
System.out.print("Enter a number between 1 y 5: ");
int intNumber = scan.nextInt();
while (intNumber < 1 || 5 < intNumber) {
System.out.print(
"Youre entered number does not match the asked set, please enter number with matches mathematical set {x∈ℕ|1<x<5}");
intNumber = scan.nextInt();
}
System.out.println("Random List : " + integerList);
for (int j = integerList.size() - 1; 0 < j; j--) {
if (integerList.get(j) % intNumber == 0) {
integerList.remove(integerList.get(j));
}
}
System.out.println("Final List, filtered out "" + intNumber + "" and its multiples: " + integerList);
}
}