use*_*379 12 java collections set
我已经向TreeSet添加了一些简单的对象,但是当我调用TreeSet的remove()和contains()方法时,它们不起作用.但是,当我遍历集合时,对象被打印出来.当对象唯一性基于对象名称属性时,应将Employee对象添加到集合中.Id属性是应该排序的值,但不是唯一的.
public class Employee {
private String name;
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// Two objects are considered equal if their names are equal
@Override
public boolean equals(Object o) {
if (o == null)
return false;
if (this == o)
return true;
if (o.getClass() == this.getClass()) {
Employee p = ( Employee) o;
if (p.getName() != null && this.getName() != null)
return this.getName().equals(p.getName());
else
return false;
} else {
return false;
}
}
}
//*******************************************************
public class EmployeeComp implements Comparator<Employee> {
// Sort Ids, but allow duplicates, hence this function is never returning 0
@Override
public int compare(Employee p1, Employee p2) {
int re = 0;
boolean scoreLt = (p1.getId() > p2.getId());
boolean scoreGt = (p1.getId() < p2.getId());
if(scoreLt)
re = -1;
if(scoreGt)
re = 1;
else
re = -1;
return re;
}
}
//*******************************************************
// Collection shall store unique names with ordered values like:
// Alex, 923
// Toni, 728
// Eddi, 232
// Peter, 232
// Eddi, 156 *** not allowed
import java.util.TreeSet;
public class Main {
private static EmployeeComp comp = new EmployeeComp();
private static TreeSet<Employee> employees = new TreeSet<Employee>(comp);
public static void main(String[] args) {
Employee p1 = new Employee();
p1.setName("Eddi");
p1.setId(232);
Employee p2 = new Employee();
p2.setName("Toni");
p2.setId(728);
Employee p3 = new Employee();
p3.setName("Peter");
p3.setId(232);
Employee p4 = new Employee();
p4.setName("Alex");
p4.setId(923);
employees.add(p1);
employees.add(p2);
employees.add(p3);
employees.add(p4);
// Here, contains() and remove() should check the object address
// and not perform their actions based on compareTo
}
}
Run Code Online (Sandbox Code Playgroud)
fge*_*fge 29
一TreeSet,插入/移除根据的结果Comparable,而不是.equals()/ .hashCode()!
这意味着,顺便说一句,你的对象Set确实实现了Comparable(如果他们没有,每次你尝试并插入一个成员时,你都会受到a ClassCastException)的欢迎.
更准确,TreeSet是一个实现SortedSet.
如果你想要一个.equals()/ .hashCode()-compatible集,请使用例如a HashSet.
为了说明,这里发生了什么BigDecimal(几个小时前在这里发布):
final BigDecimal one = new BigDecimal("1");
final BigDecimal oneDotZero = new BigDecimal("1.0");
final Set<BigDecimal> hashSet = new HashSet<>();
// BigDecimal implements Comparable of itself, so we can use that
final Set<BigDecimal> treeSet = new TreeSet<>();
hashSet.add(one);
hashSet.add(oneDotZero);
// hashSet's size is 2: one.equals(oneDotZero) == false
treeSet.add(one);
treeSet.add(oneDotZero);
// treeSet's size is... 1! one.compareTo(oneDotZero) == 0
Run Code Online (Sandbox Code Playgroud)
引述的Javadoc Comparable,这意味着BigDecimal的.compareTo()是'不相一致.equals()’.
**编辑**关于OP想要什么:
Collection不接受重复名称;Collection将根据用户的ID进行排序.如上所述,你不能拥有一个同时兼顾两者的集合.解决方案:
HashSet;ArrayList,然后使用Collections.sort().这意味着.equals()并且.hashCode()必须仅对名称起作用,而自定义Comparator将作用于id.除了Comparator自定义之外别无选择,因为它是一个.equals()在任何情况下都不一致的比较器.
至于提议的代码,存在问题.
第一:Employee覆盖.equals()但不是.hashCode().因此,Employee打破.equals()合同(其中一部分是如果两个对象相等,则它们必须具有相同的哈希码).更.hashCode()重要的是,HashSet对于工作至关重要.固定:
@Override
public int hashCode()
{
return name == null ? 0 : name.hashCode();
}
@Override
public boolean equals(final Object obj)
{
if (obj == null)
return false;
if (this == obj)
return false;
if (!(obj instanceof Employee))
return false;
final Employee other = (Employee) obj;
return name == null ? other.name == null
: name.equals(other.name);
}
Run Code Online (Sandbox Code Playgroud)
第二:比较器同样破坏,Employee因为它打破了Comparator合同(对于任何o1和o2,o1.compareTo(o2) == - o2.compareTo(o1)).固定:
public final class EmployeeComp
implements Comparator<Employee>
{
@Override
public int compare(final Employee o1, final Employee o2)
{
final int id1 = o1.getId(), id2 = o2.getId();
if (id1 == id2)
return 0;
return id1 > id2 ? 1 : -1;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,如何获取该集的排序副本:
// "set" contains the unique employees
final List<Employee> sorted = new ArrayList<Employee>(set);
Collections.sort(list, new EmployeeComp());
Run Code Online (Sandbox Code Playgroud)
DONE.
| 归档时间: |
|
| 查看次数: |
8847 次 |
| 最近记录: |