Java 如何使用另一个列表中的对象的属性创建新列表
假设我有一个特定对象的列表:Java 如何使用另一个列表中的对象的属性创建新列表,java,list,collections,java-stream,guava,Java,List,Collections,Java Stream,Guava,假设我有一个特定对象的列表: List<Student> 避免使用循环,是否可以通过使用apache collections或guava来实现这一点 哪些方法对我的案例有用?对于番石榴,您可以使用如下函数- private enum StudentToId implements Function<Student, Integer> { INSTANCE; @Override public Integer apply(St
List<Student>
避免使用循环,是否可以通过使用apache collections或guava来实现这一点
哪些方法对我的案例有用?对于番石榴,您可以使用如下函数-
private enum StudentToId implements Function<Student, Integer> {
INSTANCE;
@Override
public Integer apply(Student input) {
return input.getId();
}
}
当然,它将循环提取所有ID,但请记住,guava方法返回视图和函数仅在您尝试迭代列表时应用
如果不迭代,它将永远不会应用循环。
注意:请记住这是视图,如果您想多次迭代,最好将内容复制到其他一些列表中,如
从数学上讲,没有循环是不可能做到这一点的。为了创建离散值集到另一离散值集的映射F,F必须对原始集中的每个元素进行操作。(基本上,这样做需要一个循环。)
也就是说:
你为什么需要一份新的清单?你可能以错误的方式处理你正在解决的任何问题
如果您有一个学生的列表
,那么在遍历该列表时,您距离遍历学生的ID号只有一两步之遥
for(Student s : list)
{
int current_id = s.getID();
// Do something with current_id
}
如果您有不同类型的问题,请评论/更新问题,我们将尽力帮助您。感谢Premraj为您提供了另一个酷选项,向上投票
我使用了apache CollectionUtils和BeanUtils。因此,我对以下代码的性能感到满意:
List<Long> idList = (List<Long>) CollectionUtils.collect(objectList,
new BeanToPropertyValueTransformer("id"));
List idList=(List)CollectionUtils.collect(objectList,
新BeanPropertyValueTransformer(“id”);
值得一提的是,我将比较番石榴(Premraj提供的)的性能和我上面使用的收集工具,并决定更快的一个。如果几年后有人来到这里:
List<String> stringProperty = (List<String>) CollectionUtils.collect(listOfBeans, TransformerUtils.invokerTransformer("getProperty"));
List stringProperty=(List)CollectionUtils.collect(listOfBeans,TransformerUtils.invokerTransformer(“getProperty”);
Java 8实现方法:-
List<Integer> idList = students.stream().map(Student::getId).collect(Collectors.toList());
List idList=students.stream().map(Student::getId).collect(Collectors.toList());
Java 8 lambda表达式解决方案:
List<Integer> iDList = students.stream().map((student) -> student.getId()).collect(Collectors.toList());
List iDList=students.stream().map((student)->student.getId()).collect(collector.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]
Student first=新生(1);
第二名学生=新生(2);
第三名学生=新生(3);
MutableList=Lists.mutable.of(第一、第二、第三);
列表结果=List.collect(学生::getId);
System.out.println(结果);//[1, 2, 3]
嘿,我刚才发现了:Jon的答案很酷,但如果你看一下,它也使用了循环。任何解决方案都将使用一个循环——虽然您可能看不到它,但在内部它将需要有人应用循环来完成。要么是你,要么是你可以使用的lib。实际上,jon的答案不适合我的情况,因为我不想使用for循环。我想有一个更方便的方法去某处,但等着我找到:)首先谢谢你的回复。然而,戏剧性的是,你说需要一个新的列表是错误的。因为这取决于需求的容量和范围。因此,您的方法是错误的:)我再次提到的“无循环实现的能力”是一种更方便的方法,以避免代码无法读取和性能低下。无论如何,我已经找到了一种实现它的方法,稍后我将与大家分享。我并没有说这是一种错误的方法,但它可能是错误的方法,这取决于您试图解决的问题。无论性能如何,我都更喜欢Guava而不是apache collections,原因包括-更现代的泛型,不使用反射进行转换等。总体而言,guava比apache collections现代得多-阅读更多是的,但实际上,通过强制要求为我要转换的每种类型的对象声明额外的枚举来限制它的使用似乎不是一个好主意。这取决于您的设计-您可以使用接口sayidentification
,它定义了getId()
方法,然后您可以使用此单枚举单例模式来提取Id。guava肯定比Bean utils更有效,因为后者使用反射。在构造函数new BeanPropertyValueTransformer(“Id”)中使用属性名称作为字符串是我绝对要避免的事情。重构会很难!但我正在寻找一个解决办法。同时,我将使用番石榴的解决方案,冗长但安全。我认为必须单独定义一个函数是不雅观的。我认为这也可以匿名完成,只需一步,如何提取列表中的字符串(float等)成员?您刚刚保存了我:)如果Java<1.8,则使用Apache CollectionUtils。示例:Collection firstname=CollectionUtils.collect(userlist,TransformerUtils.invokerTransformer(“getFirstname”);如果我想要一个元组列表呢?类似于[(Id,name),(Id,name)]。并非所有Android API都支持所有1.8功能。特别是,直到API 24才支持java.util.stream。
List<Integer> idList = students.stream().map(Student::getId).collect(Collectors.toList());
List<Integer> iDList = students.stream().map((student) -> student.getId()).collect(Collectors.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]