如何使用 java.Set

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2490178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 08:21:33  来源:igfitidea点击:

How to use java.Set

javacollectionsinterfaceset

提问by sasklacz

I'm trying to make it working for quite some time,but just can't seem to get it. I have object Tower built of Block's. I've already made it working using arrays, but I wanted to learn Set's. I'd like to get similar functionality to this:

我试图让它工作很长一段时间,但似乎无法得到它。我有由 Block 建造的对象塔。我已经使用数组让它工作了,但我想学习 Set 的。我想获得与此类似的功能:

public class Tower {


public Tower(){
}

public Tower add(Block k1){

    //(...)
    //if block already in tower, return "Block already in tower"
}

public Tower delete(Block k1){

    //(...)
    //if block already dleted, show "No such block in tower"
}

}

Someone gave me some code, but I constantly get errors when trying to use it :

有人给了我一些代码,但我在尝试使用它时经常出错:

Set<Block> tower = new HashSet<Block>();

boolean added = tower.add( k1 );
if( added ) {
System.out.println("Added 1 block.");
} else {
System.out.println("Tower already contains this block.");
}

How to implement it ?

如何实施?

采纳答案by polygenelubricants

The first thing you need to study is the java.util.SetAPI.

您需要学习的第一件事是java.util.SetAPI

Here's a small example of how to use its methods:

这是一个如何使用其方法的小例子:

    Set<Integer> numbers = new TreeSet<Integer>();

    numbers.add(2);
    numbers.add(5);

    System.out.println(numbers); // "[2, 5]"
    System.out.println(numbers.contains(7)); // "false"

    System.out.println(numbers.add(5)); // "false"
    System.out.println(numbers.size()); // "2"

    int sum = 0;
    for (int n : numbers) {
        sum += n;
    }
    System.out.println("Sum = " + sum); // "Sum = 7"

    numbers.addAll(Arrays.asList(1,2,3,4,5));
    System.out.println(numbers); // "[1, 2, 3, 4, 5]"

    numbers.removeAll(Arrays.asList(4,5,6,7));
    System.out.println(numbers); // "[1, 2, 3]"

    numbers.retainAll(Arrays.asList(2,3,4,5));
    System.out.println(numbers); // "[2, 3]"

Once you're familiar with the API, you can use it to contain more interesting objects. If you haven't familiarized yourself with the equalsand hashCodecontract, already, now is a good time to start.

一旦您熟悉了 API,您就可以使用它来包含更多有趣的对象。如果您还没有熟悉equalshashCode合同,那么现在是开始的好时机。

In a nutshell:

简而言之:

  • @Overrideboth or none; never just one.(very important, because it must satisfied property: a.equals(b) == true --> a.hashCode() == b.hashCode()
    • Be careful with writing boolean equals(Thing other)instead; this is not a proper @Override.
  • For non-null references x, y, z, equalsmust be:
    • reflexive: x.equals(x).
    • symmetric: x.equals(y)if and only if y.equals(x)
    • transitive: if x.equals(y) && y.equals(z), then x.equals(z)
    • consistent: x.equals(y)must not change unless the objects have mutated
    • x.equals(null) == false
  • The general contract for hashCodeis:
    • consistent: return the same number unless mutation happened
    • consistent with equals: if x.equals(y), then x.hashCode() == y.hashCode()
      • strictly speaking, object inequality does not require hash code inequality
      • but hash code inequality necessarily requires object inequality
  • What counts as mutation should be consistent between equalsand hashCode.
  • @Override两者都有或没有;永远不会只有一个。(非常重要,因为它必须满足属性:a.equals(b) == true --> a.hashCode() == b.hashCode()
    • 写作时要小心boolean equals(Thing other);这不是一个适当的@Override.
  • 对于非空引用x, y, zequals必须是:
    • 反身:x.equals(x)
    • 对称:x.equals(y)当且仅当y.equals(x)
    • 传递性:如果x.equals(y) && y.equals(z),那么x.equals(z)
    • 一致:x.equals(y)除非对象发生变异,否则不得更改
    • x.equals(null) == false
  • 总合同为hashCode
    • 一致:除非发生突变,否则返回相同的数字
    • 符合equals:如果x.equals(y),那么x.hashCode() == y.hashCode()
      • 严格来说,对象不等式不需要哈希码不等式
      • 但哈希码不等式必然需要对象不等式
  • 什么算作变异应该在equals和之间保持一致hashCode

Next, you may want to impose an ordering of your objects. You can do this by making your type implements Comparable, or by providing a separate Comparator.

接下来,您可能希望对对象进行排序。您可以通过使您的类型实现Comparable,或通过提供一个单独的Comparator.

Having either makes it easy to sort your objects (Arrays.sort, Collections.sort(List)). It also allows you to use SortedSet, such as TreeSet.

拥有任何一个都可以轻松地对您的对象进行排序 ( Arrays.sort, Collections.sort(List))。它还允许您使用SortedSet,例如TreeSet.



Further readings on stackoverflow:

关于stackoverflow的进一步阅读:

回答by TofuBeer

Did you override equals and hashCodein the Block class?

您是否覆盖了 Block 类中的equals 和 hashCode

EDIT:

编辑:

I assumed you mean it doesn't work at runtime... did you mean that or at compile time? If compile time what is the error message? If it crashes at runtime what is the stack trace? If it compiles and runs but doesn't work right then the equals and hashCode are the likely issue.

我假设你的意思是它在运行时不起作用......你是那个意思还是在编译时?如果编译时错误信息是什么?如果它在运行时崩溃,堆栈跟踪是什么?如果它编译并运行但不能正常工作,则可能是 equals 和 hashCode 问题。

回答by TofuBeer

It's difficult to answer this question with the information given. Nothing looks particularly wrong with how you are using HashSet.

用所提供的信息很难回答这个问题。您使用 HashSet 的方式看起来没有什么特别错误。

Well, I'll hazard a guess that it's not a compilation issue and, when you say "getting errors," you mean "not getting the behavior [you] want."

好吧,我冒昧地猜测这不是编译问题,当您说“出现错误”时,您的意思是“没有得到 [您] 想要的行为”。

I'll also go out on a limb and suggest that maybe your Block's equals an hashCode methods are not properly overridden.

我也会冒昧地提出建议,也许您的 Block 等于 hashCode 方法没有被正确覆盖。

回答by Sai Sunder

Since it is a HashSet you will need to override hashCodeand equalsmethods. http://preciselyconcise.com/java/collections/d_set.phphas an example explaining how to implement hashCode and equals methods

由于它是一个 HashSet,您将需要覆盖hashCodeequals方法。http://preciselyconcise.com/java/collections/d_set.php有一个例子解释了如何实现 hashCode 和 equals 方法