当前位置: 首页 > 知识库问答 >
问题:

与集合相等且可比较

薛欣荣
2023-03-14

我在这里发布了一些代码,正确地解决了海报上的一个问题。OP希望删除重复项,并将某些特殊项置于列表的顶部。我使用了一个TreeSet和一个特殊的Comparable类,该类包装了他们正在使用的Locale,以实现他们想要的。

然后我开始想。。。正如你所做的。。。我是通过从compareTo方法返回0来消除重复,而不是通过从equals实现返回true来消除重复,这是正确指示集合中的重复(根据集合的定义)所需要的。

我不反对使用这种技术,但我是否使用了可能被视为未记录的功能?我是否可以放心地认为,今后做这种事情会继续奏效?

共有1个答案

司徒俊雄
2023-03-14

似乎这在TreeSet的JavaDoc中有很好的记录(粗体矿):

请注意,如果要正确实现Set接口,由set维护的顺序(无论是否提供显式比较器)必须与equals一致。(请参阅可比较的比较器,以获得与等于一致的精确定义。)这是因为Set接口是根据equals操作定义的,但是TreeSet实例使用其compareTo(或比较)方法执行所有元素比较,因此两个元素从集合的角度来看,通过这种方法视为相等的是相等的。集合的行为是明确定义的,即使它的顺序与等号不一致;它只是不遵守Set接口的一般契约。

下面是一个仅(?)实现了可比较的但与equals()不一致的JDK类

Set<BigDecimal> decimals = new HashSet<BigDecimal>();
decimals.add(new BigDecimal("42"));
decimals.add(new BigDecimal("42.0"));
decimals.add(new BigDecimal("42.00"));
System.out.println(decimals);

末尾的decimals有三个值,因为4242.042.00equals()而言是不相等的。但是如果您将HashSet替换为TreeSet,则结果集只包含1项(42-碰巧是第一个添加的项),因为当使用BigD<--plhd进行比较时,所有项都被认为是相等的--0/>to().

这表明,当使用与equals()不一致的类型时,TreeSet在某种程度上被“破坏”。它仍然正常工作,所有的操作都是定义良好的——它只是不遵守Set类的契约——如果两个类不是相等的(),它们就不被认为是重复的。

  • 比较与等于一致是什么意思?如果我的班级不遵循这个原则,可能会发生什么?

 类似资料:
  • 问题内容: 我在这里张贴了一些代码,可以正确解决发布者遇到的问题。OP希望删除重复项,并将某些特殊项放在列表的顶部。我在一个特殊的类中使用,包装了他们正在使用的类,以实现他们想要的。 然后我开始思考......像你一样......我是通过返回消除重复从方法,而不是通过返回从实现作为一个需要做的正确指示在重复(自定义一个的)。 我不反对使用此技术,但我是否使用了可能被视为 未记录的功能 ?我是否可以

  • JavaScript 有两种方式判断两个值是否相等。 等于操作符 等于操作符由两个等号组成:== JavaScript 是弱类型语言,这就意味着,等于操作符会为了比较两个值而进行强制类型转换。 "" == "0" // false 0 == "" // true 0 == "0"

  • 如何比较两个javascript集?我尝试使用和但都返回false。 这两个集合是等价的,因为根据定义,集合没有顺序(至少通常没有)。我看了MDN上的集合的留档,没有发现任何有用的东西。有人知道怎么做吗?

  • 我不理解javadoc中的这一行(在“API注释”子标题下): StringBuilder实现可比较但不覆盖等于。因此,StringBuilder的自然顺序与equals不一致。 我是Java的初学者,你能简单地解释一下吗?

  • 问题内容: 首先采取klurudge解决方案,使用哨兵方法(必须让您的程序不允许输入哨兵值): 假设您忘记了阻止程序中的哨兵值,用户在B字段中输入了-2147483648,而A为空。上面的代码报告为true,应报告为false,不应报告为true或null。 比较可为空字段上的相等性的最简洁方法是什么?A == B仅应报告true或false,而不管该字段是否可为空。 问题答案: 也许IS [NO

  • 但是想法 我该怎么写?