如何通过Java中的多个属性过滤列表?
我想利用Java的功能库来过滤列表中的一些条目。如何通过Java中的多个属性过滤列表?
我有一个Book对象列表,首先按Book ID排序,然后是修订版号。下面的例子,我在列表中有九个Book对象。
Book: ID 1, Revision Number 1
Book: ID 1, Revision Number 2
Book: ID 1, Revision Number 3
Book: ID 2, Revision Number 1
Book: ID 2, Revision Number 2
Book: ID 2, Revision Number 3
Book: ID 3, Revision Number 1
Book: ID 3, Revision Number 2
Book: ID 3, Revision Number 3
我想过滤列表,以便我只有每本书ID最高版本号。
Book: ID 1, Revision Number 3
Book: ID 2, Revision Number 3
Book: ID 3, Revision Number 3
确实有Java的使用类似过滤器或比较,从而可以根据多个字段我来过滤,基于共同的价值(图书ID)一些功能性的能力?我想尽量避免编写自己的函数来循环使用Collection,并尽可能地进行过滤......有什么建议吗?
什么是这样的:
List<Book> books = Arrays.asList(
new Book(1, 2),
new Book(1, 3),
new Book(2, 2),
new Book(2, 3)
);
System.out.println(
books.stream()
.collect(
groupingBy(Book::getID,
maxBy(comparingInt(Book::getRevison))
)
)
);// {1=Optional[Book{ID=1, revison=3}], 2=Optional[Book{ID=2, revison=3}]}
更新,如果在最后你只需要一个List<Book>
只使用流的Map<Integer,Optinal<Book>>
.values().stream().map(Optional::get).collect(Collectors.toList()));
的完整的例子值:
System.out.println(books.stream()
.collect(
groupingBy(Book::getID,
maxBy(comparingInt(Book::getRevison))
)
).values()
.stream()
.map(Optional::get)
.collect(Collectors.toList())
);
想要做我想做的事情,但我应该指定,它需要返回新的排序列表
@ deanmau5,这是可能的,请参阅我的更新的答案。 –
它不是基于一个以上的财产真正的过滤,但可以是你的问题的可行:
final Map<String, Book> books = list.stream().collect(
Collectors.toMap(
b -> b.getId(),
b -> b,
(b1, b2) -> {
if(b1.getNumber() > b2.getNumber()) {
return b1;
}
return b2;
})
);
它会返回地图包含ID为重点,并随书数量最多(具有唯一的ID )。
在toMap
收集器中,您可以添加merge function
,这将决定在发生同一个键时发生碰撞时要执行的操作。在这种情况下,它会返回更高数量的书。
如果你想从那个电话values()
收集。
也许一个'TreeSet'与一些比较器 – 2017-08-09 17:41:26
你可以收集它来映射无线合并功能,是否可行? – ByeBye
如果您使用的是java 8并知道要事先过滤的值,请参阅https://*.com/questions/122105/what-is-the-best-way-to-filter-a-java-collection解决方案基于[Collection.removeIf()](https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html#removeIf-java.util.function.Predicate-)可能是最好的适合你想要的东西 – csunday95