簡體   English   中英

排序LinkedHashMap <String, String[]> .entrySet()由鍵組成,但在鍵中間使用正則表達式

[英]Sorting LinkedHashMap<String, String[]>.entrySet() by the keys, but in the middle of the keys using a regex

我有一個LinkedHashMap將字符串映射到字符串數組。

鍵的格式如下:“ xxx (yyy(0.123))

基本上,我希望能夠對條目集進行排序,使其按小數部分而不是字符串的開頭進行排序。 到目前為止,我所做的是將條目集轉換為ArrayList,以便我可以嘗試在其上調用Arrays.sort,但是顯然這只是按字符串的開頭進行排序。

我目前在想的是,我將必須遍歷此數組,使用比較器將對中的每個鍵轉換為自定義類,該比較器將我想要的方式進行比較(使用正則表達式.*\\((.*)\\)\\)以找到小數點)。 但是,這聽起來似乎是很多不必要的開銷,所以我想知道是否有更簡單的方法。 提前致謝。

您的解決方案聽起來不錯。

如果遇到性能問題,則可以通過將字符串替換為包含字符串和十進制值的對象來緩沖十進制值。 然后,在排序期間無需多次重新計算。

上面提到的緩沖解決方案需要權衡取舍,弄清楚哪種技術最佳才是真正取決於整個解決方案的方法。

您是否需要使用LinkedHashMap的原因? Javadoc特別聲明

此鏈表定義了迭代順序,通常是將鍵插入映射的順序(插入順序)

TreeMap似乎更適合您要實現的目標,它使您可以在構造時提供Comparator 使用Java 8,可以通過以下方式實現:

private static final String DOUBLE_REGEX = "(?<value>\\d+(?:\\.\\d+)?)";
private static final String FIND_REGEX = "[^\\d]*\\(" + DOUBLE_REGEX + "\\)[^\\d]*";
private static final Pattern FIND_PATTERN = Pattern.compile(FIND_REGEX);

private static final Comparator<String> COMPARATOR = Comparator.comparingDouble(
    s -> {
        final Matcher matcher = FIND_PATTERN.matcher(s);
        if (!matcher.find()) {
            throw new IllegalArgumentException("Cannot compare key: " + s);
        }
        return Double.parseDouble(matcher.group("value"));
    });

private final Map<String, List<String>> map = new TreeMap<>(COMPARATOR);

編輯:如果必須是LinkedHashMapyours ),則可以始終:

map.putAll(yours);
yours.clear();
yours.putAll(map);

首先,您不能對LinkedHashMap “排序”。 LinkedHashMap根據插入順序維護迭代順序。

如果您LinkedHashMap通過使用原始地圖中的值進行插入來創建另一個LinkedHashMap ,且其順序基於已排序順序:您需要知道在初始構造未排序后添加的任何新條目。 因此,您可能想創建一個不可修改的地圖。

對於Comparator實施,您無需使其成為自定義類。 只需創建一個比較器就可以完成比較。

像這樣:

(尚未編譯,只是為了向您展示這個想法)

// assume the key is in format of "ABCDE,12345", and you want to sort by the numeric part:
Map<String, Foo> oldMap = ....; // assume you populated something in it
Map<String, Foo> sortedMap 
    = new TreeMap((a,b) -> {
                     // here I use split(), you can use regex
                     int aNum = Integer.valueOf(a.split(",")[1]);
                     int bNum = Integer.valueOf(b.split(",")[1]);
                     if (aNum != bNum )  {
                         return aNum - bNum;
                     } else {
                         return a.compareTo(b);
                     });
sortedMap.addAll(oldMap);
// now sortedMap contains your entries in sorted order.
// you may construct a new LinkedHashMap with it or do whatever you want

暫無
暫無

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

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