如何使用另一个列表中的对象的属性创建一个新列表

假设我有一个特定对象的列表:

List<Student>

我需要生成另一个列表,包括上面列表中 Studentsids:

List<Integer>

避免使用循环,是否可以通过使用 阿帕奇收藏番石榴来实现?

对于我的情况,哪些方法应该是有用的?

104162 次浏览

With Guava you can use Function like -

private enum StudentToId implements Function<Student, Integer> {
INSTANCE;


@Override
public Integer apply(Student input) {
return input.getId();
}
}

and you can use this function to convert List of students to ids like -

Lists.transform(studentList, StudentToId.INSTANCE);

Surely it will loop in order to extract all ids, but remember guava methods returns view and Function will only be applied when you try to iterate over the List<Integer>
If you don't iterate, it will never apply the loop.

Note: Remember this is the view and if you want to iterate multiple times it will be better to copy the content in some other List<Integer> like

ImmutableList.copyOf(Iterables.transform(students, StudentToId.INSTANCE));

It is Mathematically impossible to do this without a loop. In order to create a mapping, F, of a discrete set of values to another discrete set of values, F must operate on each element in the originating set. (A loop is required to do this, basically.)

That being said:

Why do you need a new list? You could be approaching whatever problem you are solving in the wrong way.

If you have a list of Student, then you are only a step or two away, when iterating through this list, from iterating over the I.D. numbers of the students.

for(Student s : list)
{
int current_id = s.getID();
// Do something with current_id
}

If you have a different sort of problem, then comment/update the question and we'll try to help you.

Thanks to Premraj for the alternative cool option, upvoted.

I have used apache CollectionUtils and BeanUtils. Accordingly, I am satisfied with performance of the following code:

List<Long> idList = (List<Long>) CollectionUtils.collect(objectList,
new BeanToPropertyValueTransformer("id"));

It is worth mentioning that, I will compare the performance of guava (Premraj provided) and collectionUtils I used above, and decide the faster one.

If someone get here after a few years:

List<String> stringProperty = (List<String>) CollectionUtils.collect(listOfBeans, TransformerUtils.invokerTransformer("getProperty"));

Java 8 way of doing it:-

List<Integer> idList = students.stream().map(Student::getId).collect(Collectors.toList());

Java 8 lambda expression solution:

List<Integer> iDList = students.stream().map((student) -> student.getId()).collect(Collectors.toList());

You can use Eclipse Collections for this purpose

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]

The accepted answer can be written in a further shorter form in JDK 16 which includes a toList() method directly on Stream instances.

Java 16 solution

List<Integer> idList = students.stream().map(Student::getId).toList();