如何使用java.Set
我试图让它工作很长一段时间,但似乎无法得到它。 我有Block的Block塔。 我已经使用数组工作了,但我想学习Set的。 我想得到类似的function:
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" } }
有人给了我一些代码,但在尝试使用时我经常遇到错误:
Set tower = new HashSet(); boolean added = tower.add( k1 ); if( added ) { System.out.println("Added 1 block."); } else { System.out.println("Tower already contains this block."); }
怎么实现呢?
您需要研究的第一件事是java.util.Set
API 。
这是一个如何使用其方法的小例子:
Set numbers = new TreeSet (); 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]"
一旦熟悉了API,就可以使用它来包含更多有趣的对象。 如果您还没有熟悉equals
和hashCode
合同,那么现在是开始的好时机。
简而言之:
-
@Override
两者都没有; 从来没有一个。 (非常重要,因为它必须满足属性:a.equals(b) == true --> a.hashCode() == b.hashCode()
- 小心写
boolean equals(Thing other)
; 这不是一个合适的@Override
。
- 小心写
- 对于非空引用
x, y, z
,equals
必须为:- 反身:
x.equals(x)
。 - symmetric:
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
之间保持一致。
接下来,您可能想要对对象进行排序。 您可以通过使类型实现Comparable
或通过提供单独的Comparator
。
有两种方法可以轻松地对对象进行排序( Arrays.sort
, Collections.sort(List)
)。 它还允许您使用SortedSet
,例如TreeSet
。
有关stackoverflow的更多信息:
- 在Java中覆盖equals和hashCode
- 何时使用Comparable vs Comparator
你在Block类中覆盖了equals和hashCode吗?
编辑:
我以为你的意思是它在运行时不起作用……你的意思是在编译时还是在编译时? 如果编译时错误信息是什么? 如果它在运行时崩溃了什么是堆栈跟踪? 如果它编译并运行但不能正常工作,则equals和hashCode可能是问题。
用给出的信息很难回答这个问题。 使用HashSet的方式没有什么特别错误。
好吧,我猜测这不是编译问题,当你说“得到错误”时,你的意思是“没有得到你想要的行为”。
我也会指出,也许你的Block等于hashCode方法没有被正确覆盖。
由于它是HashSet,您需要覆盖hashCode和equals方法。 http://preciselyconcise.com/java/collections/d_set.php有一个例子解释了如何实现hashCode和equals方法