Imagine that 我有一系列特定对象的列表:
List<Student>
我需要生成另一个列表,其中包括上述列表中学生
的id
:
List<Integer>
如何避免使用循环,是否可以通过使用apache collections或guava来实现?
哪些方法对我的情况有用?
List<Student>
我需要生成另一个列表,其中包括上述列表中学生
的id
:
List<Integer>
如何避免使用循环,是否可以通过使用apache collections或guava来实现?
哪些方法对我的情况有用?
Java 8的方法:
List<Integer> idList = students.stream().map(Student::getId).collect(Collectors.toList());
使用Guava库,您可以像这样使用Function -
private enum StudentToId implements Function<Student, Integer> {
INSTANCE;
@Override
public Integer apply(Student input) {
return input.getId();
}
}
你可以使用这个函数将学生列表转换为id,例如 -
Lists.transform(studentList, StudentToId.INSTANCE);
当然,它会循环以提取所有ID,但请记住,Guava方法返回视图(View),并且只有在尝试迭代List<Integer>时才会应用Function。如果您不迭代,则永远不会应用循环。ImmutableList.copyOf(Iterables.transform(students, StudentToId.INSTANCE));
感谢Premraj提供这个很棒的替代方案,我已经点赞了。
我使用过apache CollectionUtils和BeanUtils。因此,我对以下代码的性能感到满意:
List<Long> idList = (List<Long>) CollectionUtils.collect(objectList,
new BeanToPropertyValueTransformer("id"));
值得一提的是,我将比较Guava (由Premraj提供)和我之前使用的CollectionUtils的性能,并决定哪个更快。
Identifiable
的接口,它定义了 getId()
方法,然后你可以使用这个单例模式来通用地提取 Id。 - PremrajJava 8 lambda表达式解决方案:
List<Integer> iDList = students.stream().map((student) -> student.getId()).collect(Collectors.toList());
List<String> stringProperty = (List<String>) CollectionUtils.collect(listOfBeans, TransformerUtils.invokerTransformer("getProperty"));
已接受的答案可以在JDK 16中,直接在Stream实例上包含一个toList()方法中进一步缩短。
List<Integer> idList = students.stream().map(Student::getId).toList();
Student first = new Student(1);
Student second = new Student(2);
Student third = new Student(3);
MutableList<Student> list = Lists.mutable.of(first, second, third);
List<Integer> result = list.collect(Student::getId);
System.out.println(result); // [1, 2, 3]
如果没有循环,这是数学上不可能完成的。为了创建一个映射F,将离散值集合映射到另一个离散值集合,F必须对原始集合中的每个元素进行操作。(基本上需要使用循环来完成这个过程。)
话虽如此:
你为什么需要一个新列表?你可能正在错误地解决问题。
如果你有一个Student
列表,那么当你遍历这个列表时,只需要再迭代一两步就可以遍历学生的ID号码。
for(Student s : list)
{
int current_id = s.getID();
// Do something with current_id
}