Я пытаюсь создать общий класс, который будет иметь поведение List
, но примет Field
из String
в качестве имени свойства, которое должно определять уникальность.Например, у нас есть класс User
:
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
. Я хочу, чтобы класс давал имя UniqueList
.И чтобы иметь возможность предоставить конструктору User.class.getDeclaredField("name")
, этот список пользователей будет уникальным по имени свойства пользователя, и этот список не сможет содержать два объекта пользователя с именем «Джон», например.
На данный момент я попытался создать класс, который расширяет ArrayList<T>
и реализует Set<T>
, но у меня начался беспорядок в логике.Может быть, у кого-то уже есть что-то подобное, и он может поделиться или помочь понять, как это реализовать.В настоящее время код, который у меня есть:
public class UniqueValueList<T> extends ArrayList<T> implements Set<T> {
private String uniqueValueKey;
private Field keyField;
HashMap<Object, T> hashMap;
public UniqueValueList(Class c, String keyName) {
hashMap = new HashMap<>();
try {
keyField = c.getDeclaredField(keyName);
keyField.setAccessible(true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
@Override
public boolean add(T t) {
try {
//get value of the key from provided object.
Object keyValue = keyField.get(t);
if (hashMap.containsKey(keyValue)) {
hashMap.remove(keyValue);
}
hashMap.put(keyValue, t);
super.add(t);
return true;
} catch (IllegalAccessException | NullPointerException e) {
e.printStackTrace();
}
return false;
}
@Override
public boolean addAll(Collection<? extends T> c) {
return super.addAll(c);
}
@Override
public boolean remove(Object o) {
return super.remove(o);
}
@Override
public void clear() {
super.clear();
}
@Override
public boolean contains(Object o) {
return super.contains(o);
}
}