地図の鍵を分割し、新しいキーと関連付けられた値を使用して新しい地図を作成します

ジョン・ステフ:

私が持っているListObjectsそれらのそれぞれがX、Y値(含まれていることDoubles)と名前をString私は座標に同じ名前対応の複数のエントリを持っているように、私は私が作成することによって行うために管理され、すべての座標にすべての名前をリンクさせたいMapタイプのを<String, List<Object>>

出力の例:

One             [[0.1,0.1,0.1],[0.2,0.3,0.4]]
One,Two         [[0.1,0.1]    ,[0.4,0.5]]         
One,Two,Three   [[0.1,0.1]    ,[0.6,0.7]]

私が今やりたいことは、コンマがある名前を分割することで,、以下の結果を得ます:

One   [[0.1,0.1,0.1,0.1,0.1,0.1],[0.2,0.3,0.4,0.5,0.6,0.7]]
Two   [[0.01,0.01,0.01,0.01]    ,[0.4,0.5,0.6,0.7]]                    
Three [[0.01,0.01]              ,[0.6,0.7]]

WORKS私のコードは次のとおりです。

Map<String, List<Coordinates>> newList = coordinateList.stream()
                .collect(Collectors.groupingBy(Coordinates::getName));

これは最初に作成されますMap

第二部を行うために、私は様々な組み合わせを持つが、運と一緒に以下のことを試してみました:

newList.entrySet().stream()
        .flatMap(entry -> Arrays.stream(entry.getKey().split(","))
                .map(s -> new AbstractMap.SimpleEntry<>(s, entry.getValue())))
        .collect(Collectors.groupingBy(Map.Entry::getKey, 
                Collectors.flatMapping(entry -> entry.getValue().stream(), Collectors.toList())));

私が取得することエラーは、次のとおりです。

The method flatMapping((<no type> entry) -> {}, Collectors.toList()) is undefined for the type Collectors

変更していることを注意flatMappingmappingた作品が、問題を解決していません。

私が試したことのコードの別の変形は次のとおりです。

Map<String, List<Object>> collect1 = map.entrySet().stream()
        .flatMap(entry -> Arrays.stream(entry.getKey().split(","))
                .map(s -> new AbstractMap.SimpleEntry<>(s, entry.getValue())))
        .collect(groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue, toList())))
        .entrySet().stream()
        .flatMap(entry -> entry.getValue().stream()
                .flatMap(Collection::stream)
                .map(o -> new AbstractMap.SimpleEntry<>(entry.getKey(), o)))
        .collect(groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue, toList())));

まだ運が、私は定期的にエラーを取得していません Cannot infer type argument(s) for <R> flatMap(Function<? super T,? extends Stream<? extends R>>)

何か案は?

ラビンドラRanwala:

あなたがjava9を使用していないようです。あなたはJava9と前者のアプローチ使用している場合Collectors.flatMappingだろう作業を。しかし、私はまだ新しいを作成する際に任意のポイントが表示されないMap.Entryここに。このソリューションを見てみましょう。

private static final Pattern COMMA_DELIMITER = Pattern.compile(",\\s*");

Map<String, Set<Coordinate>> nameToCoordinates = coordinates.stream()
    .flatMap(
        c -> COMMA_DELIMITER.splitAsStream(c.getName())
            .map(n -> new Coordinate(n, c.getX(), c.getY())))
    .collect(Collectors.groupingBy(Coordinate::getName, Collectors.toSet()));

それぞれについて、グラブそれの名前を調整し、デリミタ、次いで、各そのような名前のためにその新しい名前であり、x、y座標を有する新しい座標を作成するトークンを使用してそれを分割します。そして、単にgroupingByコレクタを使用して、それを収集します。あなたが唯一の明確な座標値を維持する必要があるので、あなたは座標クラスのequalsとhashCodeメソッドをオーバーライドする必要があります。ここではそれがどのように見えるのです。

@Override
public int hashCode() {
    int result = name.hashCode();
    result = 31 * result + Double.hashCode(x);
    result = 31 * result + Double.hashCode(y);
    return result;
}

@Override
public boolean equals(Object obj) {
    return obj instanceof Coordinate && ((Coordinate) obj).getX() == x 
        && ((Coordinate) obj).getY() == y
        && ((Coordinate) obj).getName().equals(name);
}

あなたが本当に最初のステップで作成した中間のマップを使用する必要がある場合、いくつかの理由で、その後、あなたのソリューションは、このようなものです。

newList.values().stream().flatMap(Collection::stream)
    .flatMap(
        c -> COMMA_DELIMITER.splitAsStream(c.getName())
            .map(n -> new Coordinate(n, c.getX(), c.getY())))
    .collect(Collectors.groupingBy(Coordinate::getName, Collectors.toSet()));

ここでは出力があります。

{一つは= [[名前=つ、X = 0.1、Y = 0.2]、[名前=つ、X = 0.1、Y = 0.4]、[名前=つ、X = 0.1、Y = 0.3]、[名前=つ、X = 0.1、Y = 0.5]、[名前=つ、X = 0.1、Y = 0.6]、[名前=つ、X = 0.1、Y = 0.7]、二= [[名前=つ、X = 0.1 、Y = 0.4]、[名前=つ、X = 0.1、Y = 0.5]、[名前=つ、X = 0.1、Y = 0.6]、[名前=つ、X = 0.1、Y = 0.7]、スリー= [[名前=スリー、X = 0.1、Y = 0.6]、[名前=スリー、X = 0.1、Y = 0.7]}

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=204948&siteId=1