web-dev-qa-db-ja.com

文字列のストリームを分割して文字列配列のリストを生成する方法は?

私はストリームにかなり慣れていないので、助けてください(そして穏やかに)。

私がやりたいのは次のことです。私はBufferedReaderを持っています。これは、各行が「a、b」のように見えるファイルから読み取ります。例えば:

入力ファイルの例

「a、b」

「d、e」

「f、g」

これをLinkedList<String[]>に変換したいと思います。

LinkedList<String[]>

[{"a"、 "b"}、{"c"、 "d"}、{"f"、 "g"}]

ストリームアプローチを使用してこれをどのように行いますか?

これは私が試したものです:

List numbers = reader.lines().map(s -> s.split("[\\W]")).collect(Collectors.toList());

これは動作しません。私のIDEは次のフィードバックを提供します:

Incompatible types. Required List but 'collect' was inferred to R: no instance(s) of type variable(s) T exist so that List<T> conforms to List

それは示しています...私はまだストリームを理解しようとしています。

10
MWB

まず、生の型の使用を避け、代わりにList<String[]>をレシーバーの型として使用することをお勧めします。

List<String[]> numbers = reader.lines()
                               .map(s -> s.split(delimiter)) // substitute with your deilimeter
                               .collect(Collectors.toList());

LinkedList実装が必要だとおっしゃっていました。ほとんどの場合、ArrayListがデフォルトで返されるtoListを優先する必要があります現在永続性は保証されていませんが、toCollection

List<String[]> numbers = reader.lines()
                               .map(s -> s.split(delimiter)) // substitute with your deilimeter
                               .collect(Collectors.toCollection(ArrayList::new));

同様にLinkedListの場合:

List<String[]> numbers = reader.lines()
                               .map(s -> s.split(delimiter)) // substitute with your deilimeter
                               .collect(Collectors.toCollection(LinkedList::new));
8
Ousmane D.

あなたはそうすることができます、

Path path = Paths.get("src/main/resources", "data.txt");
try (Stream<String> lines = Files.lines(path)) {
    List<String> strings = lines.flatMap(l -> Arrays.stream(l.split(","))).map(String::trim)
        .collect(Collectors.toCollection(LinkedList::new));
}

ファイルの各行を読み取り、区切り文字を使用して分割します。その後、それをトリミングして、残っている空白文字を削除します。最後に結果コンテナーに収集します。

5

各行が2つの要素のタプルであるとすると、それらを2つの要素のタプルのように見えるリストに収集できます。 Javaにはタプルのネイティブタイプ(Scalaまたはpython)など)がないため、要素を表す方法を選択する必要があることに注意してください。

エントリのリストを作成できます:

_List<Map.Entry<String, String>> numbers = 
                 reader.lines()
                       .map(s -> s.split(","))
                       .map(a -> new AbstractMap.SimpleEntry<>(a[0], a[1]))
                       .collect(Collectors.toList());
_

または文字列のリスト:

_List<String> numbers = reader.lines()
                             .map(s -> s.split(","))
                             .map(a -> "{" + a[0] + "," + a[1] + "}"))
                             .collect(Collectors.toList());
_

通常、ストリームを収集するときに特定のリストの実装に固執する必要はありませんが、場合によっては必要になることがあります。この場合、toCollection(LinkedList::new)ではなくtoList()で使用するコレクションサプライヤーを指定します

5
davidxxx