属性から計算された値でグループ化しようとしています。計算された値はオプションです-もう少し明確にするために、彼は単純化された例です:
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のメソッドは自分のものではないため、変更できません。
SomeNameの「someAttribute」でフィルタリングしたいFooのリストがあります。
たとえば、私は次のようなものを持っています:
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);
}
または、ペアオブジェクトを使用すると、すべての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;
}
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加