【问题标题】:Comparator for String List字符串列表的比较器
【发布时间】:2011-05-12 04:34:42
【问题描述】:

我是 Java 新手 :)

我有 2 个字符串列表,我想知道比较两者的最有效方法是什么,并得到一个包含另一个字符串的结果数组。例如,我有一个名为 oldStrings 的列表和一个名为 Strings 的列表。我见过 Comparator 函数,但不完全理解它是如何工作的,现在我在想我可以创建一个 for 循环,循环遍历每个字符串,然后保存该字符串:

for (final String str : oldStrings) {
  if(!strings.contains(str))
  {                     
    getLogger().info(str + " is not in strings list ");
  }
}

此列表中最多有 200 个字符串。这是解决这个问题的最好方法吗?谢谢!

【问题讨论】:

  • 这是作业吗?如果是这样,请将其标记为这样,以便我们做出适当的回应。
  • 不是,它实际上是我为 Wowza 编写的一个模块,字符串列表将包含不同的流:)
  • @javamonkey79:现在不鼓励使用 homework 标签。
  • @Mark:我不知道。有相关讨论吗? TIA
  • @javamonkey79:有blog.stackoverflow.com/2010/08/the-death-of-meta-tags。但它仍然悬而未决(meta.stackexchange.com/questions/60422/is-homework-an-exception),所以请接受我所说的一粒盐。我的观点是,我们不应该强迫 OP 将其标记为家庭作业,也不应该为他们做。

标签: java string list


【解决方案1】:
Collection firstList = new ArrayList() {{
    add("str1");
    add("str2");
}};

Collection secondList = new ArrayList() {{
    add("str1");
    add("str3");
    add("str4");
}};


System.out.println("First List: " + firstList);
System.out.println("Second List: " + secondList);

// Here is main part
secondList.removeAll(firstList);

System.out.println("Result: " + secondList);  

更新: 更复杂的代码版本

Collection<String> firstList = new ArrayList<String>();
firstList.add("str1");
firstList.add("str2");

Collection<String> secondList = new ArrayList<String>();
secondList.add("str1");
secondList.add("str2");
secondList.add("str3");


System.out.println("First List: " + firstList);
System.out.println("Second List: " + secondList);

// Here is main part
secondList.removeAll(firstList);  

更新:

要获得这两个字符串列表之间的实际差异。

    Set<String> setOne = new HashSet<String>();        
    Set<String> setTwo = new HashSet<String>();
    setOne.add("1");
    setOne.add("2");
    setOne.add("5");
    setTwo.add("1");
    setTwo.add("3");
    setTwo.add("4");
    Set<String> setTwoDummy = new HashSet<String>(setTwo);
    setTwo.retainAll(setOne);        
    setTwoDummy.addAll(setOne);
    setTwoDummy.removeAll(setTwo);
    System.out.println(""+setTwoDummy);

【讨论】:

  • 啊,不,我讨厌这个成语(你如何填充列表)!它是 ArrayList 的子类,将新的具体类添加到必须由类加载器单独加载的类库中,以节省一些字符。我知道这与您实际想要展示的内容无关,所以我没有 d/v,但 IMO 的做法确实很糟糕,不应该向弱势群体展示 :-)。
  • 除非我错过了问题的重点,否则此解决方案不会无法打印不在 secondList 中的“str2”吗?我认为这个想法是为了获得 2 之间的差异 - 这将是:'str2'、'str3'、'str4'
  • @Mark:对于 ArrayList,我绝对同意你的看法,因为你总是可以在构造函数中填充 Arrays.asList( ... )。
  • @javamonkey79:我认为这个成语几乎可以用于任何集合,对吗?除了Map?
  • @Mark:这就是我的意思——我唯一一次使用上面的方法是使用地图,因为它们没有简单的方法(据我所知)用元素构造它们。
【解决方案2】:

首先,您的解决方案的问题在于它只能找到oldStrings 中的元素,而不是strings。如果您要使用这种方法,那么您还需要在另一个列表上循环。

如果这不是家庭作业,请查看来自Apache Commons Collections 的 CollectionUtils.disjunction。

【讨论】:

    【解决方案3】:

    比较两个字符串列表并有一个 包含字符串的结果数组 不属于其他人。

    描述是模棱两可的,因为我们不知道我们是否只需要来自第一个列表、第二个列表或两者的不匹配字符串。下面是两者的伪代码。

    for (String str : oldStrings)
    {
      if(strings.contains(str))
      {
        intersectionList.add(str);
      }
    }
    
    oldStrings.removeAll(intersectionList);
    strings.removeAll(intersectionList);
    result = strings.addAll(oldStrings).toArray();
    

    或者

    copyStrings = strings.clone();
    strings.removeAll(oldStrings);
    oldStrings.removeAll(copyStrings);
    result = strings.addAll(oldStrings).toArray();
    

    【讨论】:

    • 你不需要交集列表。只需执行oldStrings.removeAll(strings)strings.removeAll(oldStrings),然后将一个添加到另一个。使用intersectionList 所做的所有事情就是确保不会从 oldStrings 中删除任何不在 oldStrings 中的内容……这无论如何都不会发生。
    • 旧 = [1,2,3,4,5],当前 = [3,4,5,6],old.removeAll(current) => 旧 =[1,2], current.removeAll(old) => current = [3,4,5,6]。这不正确吗?
    • 哎呀我很抱歉,是的,你完全正确。我应该说,intersectionList 是否实际上包含交集或者在这种情况下只包含 oldStrings 的副本(oldStrings.removeAll(strings); strings.removeAll(oldStringsCopy))并不重要。如果您要麻烦手动构建列表,为什么不颠倒逻辑并直接构建析取呢? (if ( !strings.contains(str) ) { disjunct.add(str); })
    • Disjunction 似乎不是很清楚,但似乎确实更快(少了一个 removeAll)。你仍然需要 disjunct.add(strings.removeAll(oldStrings))。
    • 我更多地考虑两个循环,第二个循环交换stringsoldStrings 的角色。这样就不需要 removeAll。
    【解决方案4】:

    您应该使用 Google Guava 的 Sets 实用程序。

    Set<String> s = Sets.newHashSet("a", "b", "c", "d");
    Set<String> t = Sets.newHashSet("f", "g", "a", "c");
    Sets.SetView<String> difference = Sets.difference(s, t);
    System.out.println(difference); // prints [b, d]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 2012-08-22
      • 2023-03-04
      • 2019-04-07
      相关资源
      最近更新 更多