簡體   English   中英

拆分字符串並將其存儲到 HashMap java 8

[英]split string and store it into 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 中有偶數個元素,它就可以正常工作。

有沒有辦法處理這個? 還建議我如何使用流 java 8 使用流來完成這兩個任務(我不想使用 getTokenizeString() 方法)。

除非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操作,以確保在第一個條目之前或最后一個條目之后沒有空格。

然后,在收集到Map之前,簡單地在map步驟中拆分條目。

首先,您不必將同一個String拆分兩次。
其次,檢查數組的長度以確定給定鍵是否存在值。

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

這是假設如果鍵沒有對應的值,您希望將鍵設為null值。

或者您可以跳過list變量:

HashMap<String, String> map1 = 
    MyClass.getTokenizeString(responseString, "-")
        .stream()
        .map(s -> s.split("~"))
        .collect(Collectors.toMap(a -> a[0], a -> a.length > 1 ? a[1] : ""));
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 個命中相同的數字,例如:

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

您可以使用相同的想法將列表分成塊。

另一種簡短的方法:

String responseString = "name~peter-add~mumbai-md~v-refNo~";
Map<String, String> collect = Arrays.stream(responseString.split("-"))
                              .map(s -> s.split("~", 2))
                              .collect(Collectors.toMap(a -> a[0], a -> a.length > 1 ? a[1] : ""));
                              System.out.println(collect);

首先根據-分割字符串,然后像map(s -> s.split("~", 2))一樣map(s -> s.split("~", 2))它以創建Stream<String[]>[name, peter][add, mumbai][md, v][refNo, ]最后你將它收集到toMap因為a[0]轉到鍵, a[1]轉到值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM