繁体   English   中英

Java,从ArrayList中删除元素

[英]Java, removing elements from an ArrayList

我对此项目有疑问。 基本前提是用户输入一个短语,并且应该找到任何重复的单词以及有多少单词。

我的问题是多次输入一个单词时,例如...你好,你好,你好,你好

的输出将是;

"There are 2 duplicates of the word "hello" in the phrase you entered." 
"There are 1 duplicates of the word "hello" in the phrase you entered." 

这似乎仅在这种情况下发生。 如果我输入的随机短语中有多个单词,则显示正确答案。 我认为问题与删除重复的单词以及该单词在短语中的迭代次数有关,但是我无法解决这个问题。 我到处都添加了打印行,并且更改了以各种方式进行迭代的时间,我在Java Visualizer中进行了遍历,但仍然找不到确切的问题。 任何帮助是极大的赞赏!

这是我的在线Java课程的作业,但仅用于学习/实践,并不适合我的专业。 我只是在寻求帮助,而不是在寻找答案。

public class DuplicateWords {

public static void main(String[] args) {

    List<String> inputList = new ArrayList<String>();
    List<String> finalList = new ArrayList<String>();

    int duplicateCounter;
    String duplicateStr = "";
    Scanner scan = new Scanner(System.in);

    System.out.println("Enter a sentence to determine duplicate words entered: ");
    String inputValue = scan.nextLine();
    inputValue = inputValue.toLowerCase();
    inputList = Arrays.asList(inputValue.split("\\s+"));
    finalList.addAll(inputList);


    for(int i = 0; i < inputList.size(); i++) {
        duplicateCounter = 0;
        for(int j = i + 1; j < finalList.size(); j++) {
            if(finalList.get(i).equalsIgnoreCase(finalList.get(j))
                    && !finalList.get(i).equals("!") && !finalList.get(i).equals(".")
                    && !finalList.get(i).equals(":") && !finalList.get(i).equals(";")
                    && !finalList.get(i).equals(",") && !finalList.get(i).equals("\"")
                    && !finalList.get(i).equals("?")) {
                duplicateCounter++;
                duplicateStr = finalList.get(i).toUpperCase();
            }
            if(finalList.get(i).equalsIgnoreCase(finalList.get(j))) {
                finalList.remove(j);
            }

        }
        if(duplicateCounter > 0) {
            System.out.printf("There are %s duplicates of the word \"%s\" in the phrase you entered.", duplicateCounter, duplicateStr);
            System.out.println();
        }
    }       
}
}

根据一些建议,我编辑了我的代码,但不确定自己的方向是否正确

String previous = "";

    for(Iterator<String> i = inputList.iterator(); i.hasNext();) {
        String current = i.next();
        duplicateCounter = 0;
        for(int j =  + 1; j < finalList.size(); j++) {
            if(current.equalsIgnoreCase(finalList.get(j))
                    && !current.equals("!") && !current.equals(".")
                    && !current.equals(":") && !current.equals(";")
                    && !current.equals(",") && !current.equals("\"")
                    && !current.equals("?")) {
                duplicateCounter++;
                duplicateStr = current.toUpperCase();
            }
            if(current.equals(previous)) {
                i.remove();
            }

        }
        if(duplicateCounter > 0) {
            System.out.printf("There are %s duplicates of the word \"%s\" in the phrase you entered.", duplicateCounter, duplicateStr);
            System.out.println();
        }
    }

我将从每个单词填充一个Map<String, Integer> 每次遇到一个单词时,请增加Integer 就像是

String inputValue = scan.nextLine().toLowerCase();
String[] words = inputValue.split("\\s+");
Map<String, Integer> countMap = new HashMap<>();
for (String word : words) {
    Integer current = countMap.get(word);
    int v = (current == null) ? 1 : current + 1;
    countMap.put(word, v);
}

然后,您可以迭代Map entrySet并显示计数大于1每个keyword )。 就像是,

String msgFormat = "There are %d duplicates of the word \"%s\" in "
        + "the phrase you entered.%n";
for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
    if (entry.getValue() > 1) {
        System.out.printf(msgFormat, entry.getValue(), entry.getKey());
    }
}

您的代码存在的问题是,当您删除一个项目时,您仍然会增加索引,因此您将跳过下一个项目。 缩写形式是:

 for (int j = i + 1; j < finalList.size(); j++) {
     String next = finalList.get(i);
     if (some test on next)
         finalList.remove(next);
 }

调用remove之后,“ next”项将位于相同的索引处,因为直接删除这样的项会导致右侧的所有项都被拖移1个位置以填补空白。 要解决此问题,应在删除后添加以下行:

 i--;

那可以解决您的问题,但是,有一种更干净的方法可以做到这一点:

 String previous = "";
 for (Iterator<String> i = inputList.iterator(); i.hasNext();) {
    String current = i.next();
    if (current.equals(previous)) {
        i.remove(); // removes current item
    }
    previous = current;
 }

现在, inputList删除了所有相邻的重复项。


删除所有重复项:

List<String> finalList = inputList.stream().distinct().collect(Collectors.toList());

如果您喜欢疼痛,请“手动”进行:

 Set<String> duplicates = new HashSet<>(); // sets are unique
 for (Iterator<String> i = inputList.iterator(); i.hasNext();)
    if (!duplicates.add(i.next())) // add returns true if the set changed
        i.remove(); // removes current item

在将inputList添加到finalList之前,请从inputList删除所有重复项。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM