【问题标题】:Java: find every unique word in a list and add them to a new listJava:查找列表中的每个唯一单词并将它们添加到新列表中
【发布时间】:2016-02-11 08:06:14
【问题描述】:

我正在尝试创建一种方法来查找列表中的每个唯一单词,然后将它们添加到新列表中。我尝试了以下方法:

   public static void countWords(){
   List<String> list1 = new ArrayList<String>();
   List<String> list2 = new ArrayList<String>();

   String inText = JOptionPane.showInputDialog(null, "Type in text");
   int start = 0;    

     for(int i = 0; i < inText.length(); i++) {
        if(inText.charAt(i) == ' ') {
           list1.add(inText.substring(start,i));
           start = i;
        }                           
     }
        for(int a = 0; a < list1.size(); a++) {
           for(int j = 0; j < a; j++) {
              if(list1.get(a) != list2.get(j)) {
                 list2.add(list2.get(a));                 
              }               
           }           
        }         
}

当我运行程序并输入“hi hi hi”时,我得到了这个错误:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.get(ArrayList.java:429)
at RäknaOrd.countWords(RäknaOrd.java:24)
at RäknaOrd.main(RäknaOrd.java:6)

我该如何解决这个错误?我的方法会奏效吗?

【问题讨论】:

  • 更好的方法是基于\\s+(即空格)进行拆分,然后使用contains()List 之类的方法并将单词添加到列表中
  • 为此使用Set 效率更高

标签: java list for-loop


【解决方案1】:

你的问题在这里if(list1.get(a) != list2.get(j))

list2 为空,您正试图通过list2.get(j) 访问其中的元素

所以改为写!list2.contains(list1.get(a))

for(int a = 0; a < list1.size(); a++) {
   for(int j = 0; j < a; j++) {
         if(!list2.contains(list1.get(a))) {
           list2.add(list1.get(a));                 
        }               
     }           
 } 

【讨论】:

    【解决方案2】:

    使用Set 检测双打更有效。 Set 不允许存在同一对象的多个副本。此外,Set 可以在 log(n) 时间内检测一个项目是否已经包含在集合中(即它不必遍历集合内的所有 n 个元素)。

    代码:

    public static List<String> unique(List<String> list) {
        Set<String> unique = new HashSet<String>();
        for(String word : list)
            unique.add(word);
        return new ArrayList<String>(unique);
    }
    
    public static void main(String[] args) {
        List<String> test=new ArrayList<String>();
        test.add("hi");
        test.add("test");
        test.add("hi");
        System.out.println(unique(test));
    
    }
    

    输出:

    [test, hi]
    

    【讨论】:

      【解决方案3】:

      我相信使用 Stream 可能是一个很好的解决方案:

      list2=list1.stream().distinct().collect(Collectors.toList())
      

      【讨论】:

        【解决方案4】:

        Java 8 有一个不错的基于流的方法来返回一个删除重复项的新列表:

        List<String> list2 = list1.stream().distinct().collect(Collectors.toList());
        

        还可以拆分String 并获得List&lt;String&gt;,您可以避免这样的for 循环:

        List<String> list1 = Arrays.asList(inText.split(" "));
        

        但请记住,list1 在这种情况下是不可变的。

        演示的最小示例是:

        String inText = "hi hi hi";
        List<String> list1 = Arrays.asList(inText.split(" "));
        List<String> list2 = list1.stream().distinct().collect(Collectors.toList());
        System.out.println(list2);
        

        打印[hi]

        【讨论】:

        • 当我尝试这个程序时说:找不到符号 Collectors.toList。我需要导入一些东西才能正常工作吗?
        • import java.util.stream.Collectors;
        • 我尝试了你所说的并测试了:'List list2 = list1.stream().distinct().collect(Collectors.toList());'但是当我运行程序时输入“hi hi hi”,然后打印 list2 我得到输出“hi,hi”,就像列表中仍然存在重复一样......
        • @samtob 我在我的回答中添加了一个简单的例子,因为评论太多了。我将这些行放在main 方法中,它就像一个魅力
        【解决方案5】:
        {
            String paragraph = "I felt happy because I saw the others were happy.";
        
            String words[]=paragraph.split("\\W+");
            List<String> list2 = new ArrayList<String>();
            List<String> list1 = new ArrayList<String>();
            for(int i=0;i<words.length;i++)
            {
              if(list2.contains(words[i])==false)
              {
                 list2.add(words[i]);
              }
              else {
                 list1.add(words[i]);
              }
            }
            list2.removeAll(list1);
            Collections.sort(list2);
            System.out.print(list2);
        }
        

        输出:

        [because, felt, others, saw, the, were]
        

        【讨论】:

          猜你喜欢
          • 2013-05-19
          • 2022-01-13
          • 2021-06-24
          • 1970-01-01
          • 2013-04-14
          • 2017-03-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多