简体   繁体   中英

Making class with makes subclass object unique with hashCode and equals

I have 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);
    }


}

I thought I could make a template class that extends this LatLotoTicket class. And make id unique there and give its own hashCode and equals methods, but I couldn't figure out how to make each template has its own static idCounter and id instances.

I tried to make template Class that has:

  1. classIDCounter - with would assign id for every new class that extends this object.
  2. classID - this would avoid comparing two different objects with same id .
  3. IDCounter - counts individual objects id for each class separately
  4. id - contains id for each object

Foo and Bar classes:

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)
   }
}

in main.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

I got this far(basically nothing) and now I don't know what to do. Unique.java:

import java.util.Objects;

public class Unique<Child> {
    private static int classIDCounter = 0;
    private final int classID = classIDCounter++;

    private static int IDCounter = 0;
    private final int id = IDCounter++;

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

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

How can I achieve this? And also is there built in class that does this?

I'm using JAVA 8.

Here it is.

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;
    }
}

But remember, It isn't thread safe. And its slow. And your better don't use it because it is smell bad.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM