web-dev-qa-db-ja.com

文字列を分割してHashMapに保存するJava 8

文字列の下を分割してHashMapに保存したい。

String responseString = "name~peter-add~mumbai-md~v-refNo~"; 

まず、デリミタハイフン(-)を使用して文字列を分割し、次のようにArrayListに格納します。

 public static List<String> getTokenizeString(String delimitedString, char separator) {
    final Splitter splitter = Splitter.on(separator).trimResults();
    final Iterable<String> tokens = splitter.split(delimitedString);
    final List<String> tokenList = new ArrayList<String>();
    for(String token: tokens){
        tokenList.add(token);
    }
    return tokenList;
}
List<String> list = MyClass.getTokenizeString(responseString, "-");

次に、以下のコードを使用して、ストリームを使用してそれをHashMapに変換します。

HashMap<String, String> = list.stream()
                          .collect(Collectors.toMap(k ->k.split("~")[0], v -> v.split("~")[1]));

RefNoに対する値がないため、ストリームコレクターは機能しません。

ArrayListに偶数の要素がある場合、正しく動作します。

これを処理する方法はありますか? stream Java 8.を使用して、これらの2つのタスク(getTokenizeString()メソッドを使用したくありません)を実行するためにストリームを使用する方法)も提案します。

8
Sangam Belose

Splitterが魔法をかけていない限り、getTokenizeStringメソッドはここでは廃止されています。処理全体を単一の操作として実行できます。

Map<String,String> map = Pattern.compile("\\s*-\\s*")
    .splitAsStream(responseString.trim())
    .map(s -> s.split("~", 2))
    .collect(Collectors.toMap(a -> a[0], a -> a.length>1? a[1]: ""));

正規表現\s*-\s*を区切り記号として使用することで、空白文字を区切り記号の一部と見なし、暗黙的にエントリをトリミングします。最初のtrim操作は、エントリを処理する前に1つだけあり、最初のエントリの前または最後のエントリの後に空白がないことを確認します。

次に、mapに収集する前に、Mapステップでエントリを分割するだけです。

16
Holger

まず、同じStringを2回分割する必要はありません。
第2に、配列の長さを確認して、特定のキーに値が存在するかどうかを判断します。

HashMap<String, String> = 
    list.stream()
        .map(s -> s.split("~"))
        .collect(Collectors.toMap(a -> a[0], a -> a.length > 1 ? a[1] : ""));

これは、キーに対応する値がない場合に、キーをnull値で配置することを想定しています。

または、list変数をスキップできます。

HashMap<String, String> = 
    MyClass.getTokenizeString(responseString, "-")
        .stream()
        .map(s -> s.split("~"))
        .collect(Collectors.toMap(a -> a[0], a -> a.length > 1 ? a[1] : ""));
5
Eran
private final String dataSheet = "103343262,6478342944, 103426540,84528784843, 103278808,263716791426, 103426733,27736529279, 
103426000,27718159078, 103218982,19855201547, 103427376,27717278645, 
103243034,81667273413";

    final int chunk = 2;
    AtomicInteger counter = new AtomicInteger();
    Map<String, String> pairs = Arrays.stream(dataSheet.split(","))
            .map(String::trim)
            .collect(Collectors.groupingBy(i -> counter.getAndIncrement() / chunk))
            .values()
            .stream()
            .collect(toMap(k -> k.get(0), v -> v.get(1)));

結果:

pairs =
 "103218982" -> "19855201547"
 "103278808" -> "263716791426"
 "103243034" -> "81667273413"
 "103426733" -> "27736529279"
 "103426540" -> "84528784843"
 "103427376" -> "27717278645"
 "103426000" -> "27718159078"
 "103343262" -> "6478342944"

各2つの要素をキーと値のペアにグループ化する必要があるため、リストを2つのチャンクに分割します(counter.getAndIncrement()/ 2)は、2ヒットごとに同じ数になりますex:

IntStream.range(0,6).forEach((i)->System.out.println(counter.getAndIncrement()/2));
prints:
0
0
1
1
2
2

同じ考え方を使用して、リストをチャンクに分割できます。

0
Mohamed.Abdo