过滤只有交叉数据的ArrayLists

时间:2013-04-22 12:47:59

标签: java collections guava

我有以下课程:

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循环会更具可读性,但我只是发现了番石榴的功能。

3 个答案:

答案 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);
    }
}

你甚至可以找到最小的清单。它可以帮助它获得一点性能。