【发布时间】:2019-08-08 12:17:25
【问题描述】:
我正在尝试创建具有List 行为的通用类,但接受String 的Field 作为应该确定唯一性的属性名称。
例如我们有类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"),这将使这个用户列表通过用户的属性名称是唯一的,并且这个列表将不能包含两个名为“John”的用户对象。
至于现在,我尝试创建扩展 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);
}
}
【问题讨论】:
-
我认为与其扩展 ArrayList 并同时实现 Set ,不如只扩展 ArrayList 并覆盖其 add 方法。检查列表是否包含 list.contains(data) 如果不包含则仅将其添加到列表中,这将有助于独特性。
-
这是常规方式,我必须为此进行嵌套 for 循环,我试图避免它。这就是我实施 set 的原因
-
然后你可以使用 LinkedHashset。从而保持顺序和唯一性。
标签: java generics arraylist set