在 Java 中检查字符串集中的包含情况

发布于 2024-10-04 08:38:16 字数 425 浏览 0 评论 0 原文

我有一组 String[]。我想检查这个 Set 是否包含另一个 String[]。

Set<String[]> s  = new HashSet<String[]>();
s.add(new String[] {"lucy", "simon"});
System.out.println(s.contains(new String[] {"lucy", "simon"}));

然而,打印的是 false。我的猜测是这是因为只比较引用而不是实际的字符串。看来,我唯一的选择就是创建一个类,比如 Phrase,并实现 hashCode()equals() (使用 Arrays.hashCode( ...))。

还有其他方法可以实现我想要的吗?

I have a Set of String[]. I want to check whether this Set contains another String[].

Set<String[]> s  = new HashSet<String[]>();
s.add(new String[] {"lucy", "simon"});
System.out.println(s.contains(new String[] {"lucy", "simon"}));

However, false is printed. My guess is this is because only the references are being compared and not the actual Strings. It seems, the only option I have is to create a class, say Phrase, and implement hashCode() and equals() (that use Arrays.hashCode(...)).

Is there any other way to achieve what I want?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

撩人痒 2024-10-11 08:38:16

您的猜测是正确的:数组 ([]) 没有实现深度 equals 方法:如果它们是同一实例,则它们相等。

最简单的解决方案是:用 List 替换 String[]

另一种方法(但我不推荐它)是实现你自己的 Set,它不会基于 Object.equals 但基于 java.util.Arrays.equals(Object[]a, Object[]b)

Your guess is correct: arrays ([]) do not implement a deep equals method: they are equals if they are the same instance.

The simplest solution would be: replacing String[] by List<String>

An other way (but i do not recommend it) is to implement your own Set, which does not based on Object.equals but on java.util.Arrays.equals(Object[]a, Object[]b)

≈。彩虹 2024-10-11 08:38:16

String[] 转换为 List ,效果应该很好。

Set<List<String>> s  = new HashSet<List<String>>();
s.add(Arrays.asList("lucy", "simon"));
System.out.println(s.contains(Arrays.asList("lucy", "simon")));

Convert that String[] to List<String> and it should work out pretty well.

Set<List<String>> s  = new HashSet<List<String>>();
s.add(Arrays.asList("lucy", "simon"));
System.out.println(s.contains(Arrays.asList("lucy", "simon")));
想挽留 2024-10-11 08:38:16

String[] 的元素是否可以采用不同的顺序,并且仍然使整个数组被视为等于另一个包含不同顺序的相同元素的数组?如果是,那么您确实最好实现一个容器类并覆盖 equals 和 hashcode。

如果不是,并且如果将内部元素存储为列表而不是数组是可接受的替代方案,那么您可以这样做:

package com.stackoverflow;


import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


public class StringContainment {

  public static void main(final String[] args) {
    final Set<String[]> s = new HashSet<String[]>();
    final Set<List<String>> s2 = new HashSet<List<String>>();

    s.add(new String[] {"lucy", "simon"});
    s2.add(Arrays.asList(new String[] { "lucy", "simon" }));

    System.out.println(s.contains(new String[] {"lucy", "simon"})); // false
    System.out.println(s2.contains(Arrays.asList(new String[] {"lucy", "simon"}))); // true
  }

}

第一次检查将返回 false,第二次检查将返回 true。
如果您可以使用列表,这种方式可能会更容易。

如果你不能,你仍然可以使用它,只要你不需要太频繁地进行这种比较(从性能角度来说,这绝对不是一个好主意)。

Can the elements of the String[] be in different orders and still make the whole array be considered equal to another array containing the same elements in another order? If yes, you'd indeed be better off implementing a container class and overriding equals and hashcode.

if not, and if storing the internal elements as Lists instead of arrays is an acceptable alternative, then you could do this:

package com.stackoverflow;


import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


public class StringContainment {

  public static void main(final String[] args) {
    final Set<String[]> s = new HashSet<String[]>();
    final Set<List<String>> s2 = new HashSet<List<String>>();

    s.add(new String[] {"lucy", "simon"});
    s2.add(Arrays.asList(new String[] { "lucy", "simon" }));

    System.out.println(s.contains(new String[] {"lucy", "simon"})); // false
    System.out.println(s2.contains(Arrays.asList(new String[] {"lucy", "simon"}))); // true
  }

}

The first check will return false, the second true.
Might be easier that way if you can use lists.

If you can't, you could still use this as long as you don't need to do this comparison too often (it's definitely not a good idea performance-wise).

煞人兵器 2024-10-11 08:38:16

听起来你已经回答了你的问题。一种选择正如您已经说过的那样。另一种方法是使用Set>,因为equals(Object)的API说:

比较指定对象与此集合是否相等。

Sounds like you've already answered your question. One option is as you already stated. The another would be to use Set>, since the API for equals(Object) says:

Compares the specified object with this collection for equality.

栖竹 2024-10-11 08:38:16

使用 Set>Set> 而不是 Set

代码:

List<String> s1=Arrays.asList("1","2"),s2=Arrays.asList("1","2");
System.out.println(s1.equals(s2) + " "+s1.hashCode()+ " "+s2.hashCode());

输出:

true 2530 2530

Use Set<Set<String>> or Set<List<String>> instead of Set<String[]>

Code:

List<String> s1=Arrays.asList("1","2"),s2=Arrays.asList("1","2");
System.out.println(s1.equals(s2) + " "+s1.hashCode()+ " "+s2.hashCode());

Output:

true 2530 2530
若能看破又如何 2024-10-11 08:38:16

我只是循环并调用 Arrays.equals:

像这样的东西:

boolean contains(Set<String[]> s, String[] item) {
  for(String[] toCompare: s) {
    if(Arrays.equals(toCompare, item)) {
        return true;
    }
  }
  return false;
}

不确定它是否是最快的,但它应该很好地完成工作

I'd just loop through and call Arrays.equals:

something like this:

boolean contains(Set<String[]> s, String[] item) {
  for(String[] toCompare: s) {
    if(Arrays.equals(toCompare, item)) {
        return true;
    }
  }
  return false;
}

not sure if it's the fastest but it should do the job nicely

浪漫之都 2024-10-11 08:38:16

Java8流介绍您可以通过以下方式进行操作:

Boolean res = s.stream()
  .anyMatch(elm -> elm.equals("lucy") || elm.equals("simon"));

With Java8 stream introduction you can do it the following way:

Boolean res = s.stream()
  .anyMatch(elm -> elm.equals("lucy") || elm.equals("simon"));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文