我有以下课程:
public class School{
List<ClassRoom> classRooms;
}
public class ClassRoom{
List<Student> students;
}
public class Student{
String name;
List<Long> typeIdList;
}
我需要得到typeId
,它们是给定教室中所有学生的共同因素。
为了能够让所有具有typeID = 123的特定教室的学生,我执行以下操作:
final long typeIdToSearchFor = ...;
Collection<Student> filtered = Collections2.filter(students,
new Predicate<Student>() {
@Override
public boolean apply(Student s) {
return s.typeId == typeIdToSearchFor;
}
}
);
只是想知道番石榴是否可以处理这样的事情? 通过交集我的意思是它必须在所有实例中出现以考虑这种类型。
我知道for
循环会更具可读性,但我只是发现了番石榴的功能。
答案 0 :(得分:1)
您可以使用Multiset
来计算出现次数:
ClassRoom classRoom = /* comes from somewhere */;
List<Student> students = classRoom.getStudents();
// Aggregate all the typeIds.
Multiset<Long> typeIds = HashMultiset.create();
for (Student student : students) {
// Assuming a student doesn't have duplicated typeIds:
typeIds.addAll(student.getTypeIds());
}
// Find which typeIds are present for all the students.
for (Multiset.Entry<Long> entry : typeIds.entrySet()) {
if (entry.getCount() == students.size()) {
System.out.println(entry.getElement());
}
}
答案 1 :(得分:0)
如果您要检查所有Student
是否具有特定typeId
,请使用现有谓词的Iterables.all
。
您还可以使用Multimap
创建Student
typeId
Multimaps.index()
个Multimap<Long, Student> studentsByTypeId = Multimaps.index(students, new Function<Student, Long>() {
public Long apply(Student s) {
return s.typeId;
}
};
索引:
typeId
然后,您可以使用studentsByTypeId.keySet()
获取唯一的typeId
。
您可以使用studentsByTypeId.keySet().size() == 1
检查它们是否全部共享{{1}}。
答案 2 :(得分:0)
如果你想要与你相交的那些不应该与特定的那个相比,你至少应该检查它是否包含在另一个集合的id中。像这样:
new Predicate<Student>() {
@Override
public boolean apply(Student s) {
return otherIds.contains(s.typeId);
}
}
但我仍然认为,如果你在两个集合上进行二元搜索(在订购之后),你可以更快地得到答案。像这样的东西
Collections.sort(list1);
Collections.sort(list2);
List<E> intersected = new ArrayList<E>();
for(E element : list1){
if(Collections.binarySearch(list2, element) >= 0){
intersected.add(element);
}
}
你甚至可以找到最小的清单。它可以帮助它获得一点性能。