【问题标题】:Use of .contains in an ArrayList<String> went wrong [closed]在 ArrayList<String> 中使用 .contains 出错了[关闭]
【发布时间】:2016-02-24 01:46:36
【问题描述】:

我必须检查一个字符串列表,如果之前没有处理过这个字符串,那么我们对这个字符串做一些处理。对于他的问题,我在处理后将每个字符串添加到ArrayList&lt;String&gt;,并在处理之前检查该字符串是否存在于不存在的列表中。但是由于某种原因,尽管String存在于数组列表中,但它不起作用。

ArrayList<String> strings=new ArrayList<String>();
while(true) {
   if(!strings.contains(someString)) {
      System.out.println(someString);
      strings.add(someString);
   }
}

编辑

当我提到它不起作用时,我的意思是 if 条件应该为相似的字符串返回 false(因为它们相互包含),但是相反,它并没有这样做,然后程序进入 @ 987654324@ 声明。

输入:

http://www.foo.barhttp://www.foo.bar/http://www.foo.bar

输出:

应该只打印第一个 URL。

【问题讨论】:

  • “它不起作用”是什么意思?请准确描述您预期会发生什么,以及实际发生了什么。包括您遇到的任何异常/堆栈跟踪。
  • @ErwinBolwidt 它不起作用意味着对于相同或非常相似的字符串,它不会返回 false。所以它进入了不正确的if 语句。
  • 发布不起作用的确切代码。你说的是“非常相似”——嗯,非常相似并不是完全相同,所以contains 方法当然会返回false
  • 如果您只想确定字符串是否已经存在,请使用哈希集。
  • 请提供实际输出和预期输出的示例。就像埃尔文所说的那样。 @寂寞

标签: java string arraylist


【解决方案1】:

尝试这样做:

while(true) {//dont know why you have this endless loop
   boolean flag = false;
   for (String s : strings) {
       if (s.toUpperCase().contains(someStrings.toUpperCase()) || someStrings.toUpperCase().contains(s.toUpperCase())) {
           flag = true;
           //the string already exists
           break;
       }
   }
   if (flag) {
   //to do if string already exists
   } else {
       strings.add(someStrings);
   }
}

我现在明白了。请再次检查。

【讨论】:

  • 我认为它不能正常工作。第一次运行,列表添加http://www.foo.bar。然后,列表将添加http://www.foo.bar/。因为bar 不包含bar/
  • 我更新了我的答案。请检查。 @寂寞
  • 请我也回答@Manh Le
  • 它工作正常。 @lonesome 进行高级比较,您应该使用 Regular expression 来涵盖您的情况。我们需要根据您的示例修改比较条件,但是根据您的真实数据,它可能不起作用。
  • 因为欧文的答案更短,更容易匹配我的代码,所以我只支持你的。
【解决方案2】:

您在ArrayList(“http://www.foo.bar”和“http://www.foo.bar/”)中放入了不同的字符串,并且您希望contains 方法将它们视为相同。那是行不通的; contains 仅在字符串完全相同时有效。

鉴于有数百种可能的方式可以将字符串视为“相似”,因此没有对此类“相似性检查”的内置支持也就不足为奇了。

一个简单的方法是在将它们放入列表之前canonicalize你的字符串。

在您的情况下,您希望字符串被视为相同,无论它们是否以斜杠结尾。您可以通过确保字符串 always 在将它们放入列表之前以斜杠结尾来规范化它们:

if (!someString.endsWith("/")) {
    someString += "/";
}

(另一种选择是在字符串之间考虑edit-distance;但是您需要一个特殊的数据结构来存储它们,普通的ArrayList 是不够的。)

【讨论】:

    【解决方案3】:

    我的立场已得到纠正——下面的内容与 ArrayList.contains() 相同。

    private static ArrayList<String> myList = new ArrayList<String>();
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) myList.add("aString" + i);
        if (myList.contains("aString3")) System.out.println("Contains is true");
        else System.out.println("Contains is false");
    }
    

    打印“包含为真”。很抱歉提供了不好的信息。

    当您使用 ArrayList.contains(Object) 时,您正在检查列表是否包含该确切对象。在您的情况下,您希望逐个字符串比较而不是对象比较。

    for (String string : strings) {
      if (someString.contains(string)) {
        //Do stuff
      }
    }
    

    【讨论】:

    • 但是如果一个字符串是 book 而另一个是 books 我想将它们视为同一件事。 .equal会处理这个吗?
    • 不会使用 toString() 也适用于他的情况,因为它会将对象转换为字符串?只是大声思考。还没想好。
    • 那么我认为,您可以将 .equals 替换为 .contains()。对吗?
    • 您发布的内容正是contains 方法的作用。没有区别。所以它不会解决问题。
    • @lonesome:我认为@JanLeeYu 的推荐会解决你的问题。当您在ArrayList 上使用.contains 时,您的对象必须完全相等。
    猜你喜欢
    • 2013-12-04
    • 2013-05-08
    • 2013-07-06
    • 2013-07-05
    • 2010-09-16
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    • 2013-10-18
    相关资源
    最近更新 更多