当前位置:  开发笔记 > 编程语言 > 正文

使用Comparator时从TreeSet丢失数据

如何解决《使用Comparator时从TreeSet丢失数据》经验,为你挑选了1个好方法。

我有以下代码,将Employees's根据他们的经验进行排序.

我正在增加2名不同name且相同的员工experience.我期待最终set会有2名员工,但我只有一名员工.

我也覆盖equalshashcode,任何一个可以告诉我为什么我收到只有一个组的员工.

测试类

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.junit.Test;

public class SetWithComparator {


    @Test
    public void testComparatorWithSet() {

        Comparator comparator =
                (emp1, emp2) -> emp1.getYearOFExp().compareTo(emp2.getYearOFExp());

        Set empSet = new TreeSet<>(comparator);

        Employee e1 = new Employee();
        e1.setName("Employee-1");
        e1.setYearOFExp(12f);

        Employee e2 = new Employee();
        e2.setName("Employee-2");
        e2.setYearOFExp(12f);

        empSet.add(e1);
        empSet.add(e2);

    }

}

模型类

class Employee {


    private String name;
    private Float yearOFExp;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Float getYearOFExp() {
        return yearOFExp;
    }

    public void setYearOFExp(Float yearOFExp) {
        this.yearOFExp = yearOFExp;
    }

    @Override
    public boolean equals(Object obj) {

        if (obj instanceof Employee) {

            Employee e = (Employee) obj;
            return new EqualsBuilder().append(name, e.getName()).isEquals();
        } else {
            return false;
        }

    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(name).toHashCode();
    }

}

Lachezar Bal.. 8

因为比较器与你的equals方法不一致.请查看比较器的文档.

当且仅当c.compare(e1,e2)== 0具有与每个e1的e1.equals(e2)相同的布尔值时,比较器c对一组元素S施加的排序被称为与等于一致.和S中的e2

当使用能够强加与equals不一致的排序的比较器来排序有序集(或有序映射)时,应该谨慎行事.假设带有显式比较器c的有序集(或有序映射)与从集合S中绘制的元素(或键)一起使用.如果由S对S施加的排序与equals不一致,则排序集(或有序映射)将表现得"奇怪".特别是有序集(或有序映射)将违反集合(或映射)的一般契约,其以等于的方式定义.

您可以在Comparable的文档中暗示您遇到的确切行为(尽管您使用比较器):

例如,如果添加两个键a和b使得(!a.equals(b)&& a.compareTo(b)== 0)到不使用显式比较器的有序集,则第二个add操作返回false (并且有序集的大小不会增加)因为a和b从排序集的角度来看是等价的.

在你的情况下:comparator.compare(e1, e2)0,e1.equals(e2)false.



1> Lachezar Bal..:

因为比较器与你的equals方法不一致.请查看比较器的文档.

当且仅当c.compare(e1,e2)== 0具有与每个e1的e1.equals(e2)相同的布尔值时,比较器c对一组元素S施加的排序被称为与等于一致.和S中的e2

当使用能够强加与equals不一致的排序的比较器来排序有序集(或有序映射)时,应该谨慎行事.假设带有显式比较器c的有序集(或有序映射)与从集合S中绘制的元素(或键)一起使用.如果由S对S施加的排序与equals不一致,则排序集(或有序映射)将表现得"奇怪".特别是有序集(或有序映射)将违反集合(或映射)的一般契约,其以等于的方式定义.

您可以在Comparable的文档中暗示您遇到的确切行为(尽管您使用比较器):

例如,如果添加两个键a和b使得(!a.equals(b)&& a.compareTo(b)== 0)到不使用显式比较器的有序集,则第二个add操作返回false (并且有序集的大小不会增加)因为a和b从排序集的角度来看是等价的.

在你的情况下:comparator.compare(e1, e2)0,e1.equals(e2)false.

推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有