[英]Java 8 Streams Grouping by an Optional Attribute
我試圖通過屬性的計算值進行分組。 計算出的值是可選的 - 為了更清楚一點,他是一個簡化的例子:
class Foo:
int id;
Group group;
.. some other stuff
class Group:
String groupId;
... (some other stuff)
class SomeName:
String someAttribute;
class Converter:
public Optional<SomeName> getSomenameFromGroup(Group)
我無法更改Converter中的方法,因為它不屬於我。
我有一個Foo列表,我希望通過SomeName的“someAttribute”進行過濾。
例如,我有這樣的事情:
Map<String, List<Foo>> fooBySomeName =
fooList.stream().collect(Collectors
.groupingBy(foo -> {
Optional<SomeName> name =
converter.getSomenameFromGroup(foo.getGroup.getGroupId());
return name.isPresent() ? name.get().someAttribute() : "";
}));
但問題是,如果groupingBy語句中沒有該名稱,我在地圖中不需要任何內容。 我有這樣的事情:
fooBySomeNames.remove("")
我認為可以刪除由該鍵分組的地圖中的任何內容,但是在groupingBy語句中是否有更清晰或更正確的方法來執行此操作?
您可以使用過濾器刪除條目,如下所示。
Map<String, List<Foo>> fooBySomeName = fooList.stream()
.filter(foo -> fooToSomeAttribute(foo).isPresent())
.collect(Collectors.groupingBy(foo -> fooToSomeAttribute(foo).get()));
private static Optional<String> fooToSomeAttribute(Foo foo)
{
return Optional.ofNullable(foo)
.map(Foo::getGroup)
.flatMap(new Converter()::getSomenameFromGroup)
.map(SomeName::getSomeAttribute);
}
或者,使用pair對象,可以避免每個Foo的someAttribute的雙重計算:
Map<String, List<Foo>> fooBySomeName = fooList.stream()
.filter(Objects::nonNull)
.map(FooAndSomeAttribute::new)
.filter(pair -> pair.getSomeAttribute().isPresent())
.collect(Collectors.groupingBy(
pair -> pair.getSomeAttribute().get(),
Collectors.mapping(
FooAndSomeAttribute::getFoo,
Collectors.toList())));
private static class FooAndSomeAttribute
{
private final Foo foo;
private final Optional<String> someAttribute;
public FooAndSomeAttribute(Foo foo)
{
this.foo = foo;
this.someAttribute = Optional.ofNullable(foo)
.map(Foo::getGroup)
.flatMap(new Converter()::getSomenameFromGroup)
.map(SomeName::getSomeAttribute);
}
public Foo getFoo()
{
return foo;
}
public Optional<String> getSomeAttribute()
{
return someAttribute;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.