使用hashCode和equals使class子类对象唯一

时间:2015-04-18 08:53:37

标签: java templates hash

我有LatLotoTicket.java

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

public class LatLotoTicket {
    private static int counterID = 0;
    private final int id = counterID++;
    private final String address;
    private final Set<Integer> userNumbers;

    public LatLotoTicket(String address, Set<Integer> userNumbers) {
        this.address = address;
        this.userNumbers = userNumbers;
    }

    public LatLotoTicket(LatLotoTicket ticket) {
        this.address = ticket.address;
        this.userNumbers = ticket.getUserNumbers();
    }

    public String getAddress() {
        return address;
    }

    public Set<Integer> getUserNumbers() {
        return new HashSet<>(userNumbers);
    }

    @Override
    public boolean equals(Object o) {
        if(this == o) return true;
        if(o == null || getClass() != o.getClass()) return false;
        LatLotoTicket that = (LatLotoTicket) o;
        return Objects.deepEquals(this.id, that.id);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(id);
    }


}

我以为我可以创建一个扩展此LatLotoTicket类的模板类。并将ID设为唯一,并提供自己的hashCodeequals方法,但我无法弄清楚如何使每个模板都有自己的静态idCounter和{{1}实例。

我尝试制作具有以下内容的模板类​​:

  1. id - with会为每个扩展此对象的新类分配classIDCounter
  2. id - 这样可以避免将两个不同的对象与classID进行比较。
  3. id - 分别计算每个班级的单个对象IDCounter
  4. id - 每个对象包含id
  5. Foo和Bar课程:

    id

    在main.java中:

    public class Foo extends Unique<Foo> {
       public Foo() {
           System.out.println("Object ID "super.id + " class id " + super.classID)
       }
    }
    
    public class Bar extends Unique<Bar> {
       public Foo() {
           System.out.println("Object ID "super.id + " class id " + super.classID)
       }
    }
    

    我到目前为止(基本上没什么),现在我不知道该怎么做。 Unique.java:

    Foo foo1 = new Foo(); // Object ID 1 class id 1
    Foo foo2 = new Foo(); // Object ID 2 class id 1
    Bar bar1 = new Bar(); // Object ID 1 class id 2
    Bar bar2 = new Bar(); // Object ID 2 class id 2
    Foo foo3 = new Foo(); // Object ID 3 class id 1
    

    我怎样才能做到这一点?还有内置的课程吗?

    我正在使用JAVA 8。

1 个答案:

答案 0 :(得分:0)

在这里。

public class Unique {

    private static final Map<Class, AtomicInteger> idCounters = new HashMap<>();
    private static final Map<Class, Integer> classIDs = new HashMap<>();
    private static int classIDCounters2 = 0;

    private final int id;

    public Unique() {
        this.id = nextIdFor(getClass());
    }

    private static int nextIdFor(Class<? extends Unique> aClass) {
        AtomicInteger counter = idCounters.get(aClass);
        if(counter == null){
            counter = new AtomicInteger(0);
            idCounters.put(aClass, counter);
        }
        return counter.incrementAndGet();
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Unique unique = (Unique) o;
        return getClassID() == unique.getClassID() && getId() == unique.getId();
    }

    @Override
    public int hashCode() {
        int result = getClassID();
        result = 31 * result + getId();
        return result;
    }

    public int getId() {
        return id;
    }

    public int getClassID() {
        Integer classId = classIDs.get(getClass());
        if(classId == null){
            classId = classIDCounters2++;
            classIDs.put(getClass(), classId);
        }
        return classId;
    }
}

但请记住,它不是线程安全的。而且它很慢。你最好不要使用它,因为它味道很差。