Java: 在列表中查找每个唯一的单词并将它们添加到新列表中

3
我正在尝试创建一个方法,该方法可以找到列表中的每个唯一单词,并将它们添加到新列表中。我已经尝试了以下代码:
   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+(即空格)进行分割,然后使用Listcontains()方法将单词添加到列表中。 - TheLostMind
使用“Set”更有效率。 - Niels Billen
5个回答

5
Java 8有一个很好的基于流的方法来返回一个新的列表,并删除重复项:
List<String> list2 = list1.stream().distinct().collect(Collectors.toList());

另外,要拆分字符串并获取一个List<String>,您可以避免使用类似于此的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。我需要导入什么才能使其正常工作吗? - samtob
2
import java.util.stream.Collectors; - Manos Nikolaidis
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - samtob
@samtob,我在我的回答中添加了一个简单的示例,因为它太长了,不适合评论。我将这些行放在了一个“main”方法中,它运行得非常好。 - Manos Nikolaidis

1
你的问题在这里:if(list1.get(a) != list2.get(j)) list2是空的,你试图通过list2.get(j)访问其中的元素。
因此,你应该写成!list2.contains(list1.get(a))。请注意,保留HTML标签。
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));                 
        }               
     }           
 } 

1
使用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]

1

我认为使用流可能是一个不错的解决方案:

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

1
{
    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]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接