I have a List<A>
that contains some objects A
with the attribute id. What I need is the list to contain only one object for an id.
public List<A> findAllA() {
List<A> aList; // fetches the elements from db
HashMap<Long, A> aMap = new HashMap<>();
for (A a: aList) {
aMap.put(a.getId(), a);
}
return new ArrayList<>(aMap.values());
}
So I put my list elements in a HashMap
, because a HashMap
holds distinct keys. Then a new ArrayList<A>
with the values of the map is returned. This does work fine, but is there a more efficient way to achieve the result? Or at least a shorter one?
答案 0 :(得分:2)
如果您要查找较少的字符/代码行,可以使用Stream
s:
return aList.stream().distinct().collect(Collectors.toList());
这假设您的A
班级会覆盖equals
,并且A
的两个实例等于且当且仅当它们具有相同的ID时。
当然,如果是这种情况,您也可以使用HashSet
来消除重复项:
return new ArrayList<A>(new HashSet<A>(alist));
如果您的A
课程未覆盖equals
(或equals
上述行为不正常),请使用HashMap
,这是一个有效的线性时间解。你无法在平均运行时间方面做得更好。
答案 1 :(得分:0)
使用Java 8流:
List<A> aList; // fetches the elements from db
Collection<A> original= aList.stream()
.<Map<Integer, A>> collect(HashMap::new,(m,e)->m.put(e.getId(), e), Map::putAll).values();
答案 2 :(得分:0)
如果equals()/hashCode()
方法依赖于id
,您只需从Set
创建List
:
Set<A> set = new HashSet<>(aList);
Set
根据equals()
删除重复的元素等于
如果Set
类型不合适,您仍可将其转换为List
:
List<A> newList = new ArrayList<A>(new HashSet<A>(alist));
答案 3 :(得分:0)
按照你的逻辑,你也可以尝试这样做
public List<A> findAllA() {
List<A> aList; // fetches the elements from db
HashMap<Long, A> aMap = new HashMap<>();
List<Long> processedList = new ArrayList<>();
for (A a: aList) {
if(!processedList.contains(a.getId())) {
processedList.add(a.getId());
aMap.put(a.getId(), a);
}
}
return new ArrayList<>(aMap.values());
}