簡體   English   中英

Java 流和過濾到 Map 產生錯誤

[英]Java stream and filtering to a Map producing an error

我正在嘗試使用 Java 流來創建一個包含貨幣代碼和字符串描述的地圖。 當我嘗試添加項目 1 到 6 時,代碼有效,但是當我嘗試添加項目 7(其中貨幣代碼參數未初始化)時,出現以下錯誤。

Exception in thread "main" java.lang.NullPointerException
    at java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011)
    at java.util.concurrent.ConcurrentHashMap$KeySetView.add(ConcurrentHashMap.java:4595)
    at Test.lambda$6(Test.java:73)

如何修改以下代碼以過濾出未初始化貨幣代碼值的項目? 我原以為過濾掉空值應該可以解決問題,但這並不完全有效。

public class Test {

    public static void main(String[] args) {
        Currency item1 = new Currency();
        item1.setCurrencyCode("USD");
        Currency item2 = new Currency();
        item2.setCurrencyCode("GBP");
        Currency item3 = new Currency();
        item3.setCurrencyCode("GBP");
        Currency item4 = new Currency();
        item4.setCurrencyCode("AUS");
        Currency item5 = new Currency();
        item5.setCurrencyCode("USD");
        Currency item6 = new Currency();
        item6.setCurrencyCode("");
        Currency item7 = new Currency();

        List<Currency> list = new ArrayList<>();
        list.add(item1);
        list.add(item2);
        list.add(item3);
        list.add(item4);
        list.add(item5);
        list.add(item6);
        list.add(item7);

        Map<String, String> distinctCurrencyCodes = list.stream()
                .filter( distinctByKey(p -> p.getCurrencyCode()) )
                .filter(p -> (!StringUtils.equals(p.getCurrencyCode(), "USD")))
                .filter(p -> p.getCurrencyCode() != "" || p.getCurrencyCode() != null)
                .map(p -> p.getCurrencyCode() )
                .collect( Collectors.toMap(p -> p, p -> "Blah") );

        for (Map.Entry<String, String> entry : distinctCurrencyCodes.entrySet()) {
            System.out.println(entry.getKey() + "/" + entry.getValue());
        }
    }

    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
    }
}

問題實際上出在distinctByKey()方法中。

當您發送一個空值以添加到 Set 中時,就會發生異常。 只需將您的 distinctByKey() 方法更改為此。 我在這個方法中處理了 null。

public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    Set<Object> seen = ConcurrentHashMap.newKeySet();
    return t -> {
        Object currencyName = keyExtractor.apply(t);
        if(currencyName == null)
            return false;
        return seen.add(currencyName);
    };
}

如果您這樣做,則無需再添加此過濾器:

.filter(p -> p.getCurrencyCode() != "" && p.getCurrencyCode() != null)

你可以刪除這個。 所以你過濾的部分將是:

Map<String, String> distinctCurrencyCodes = list.stream()
            .filter(distinctByKey(p -> p.getCurrencyCode()))
            .filter(p -> (!StringUtils.equals(p.getCurrencyCode(), "USD")))
            .map(p -> p.getCurrencyCode() )
            .collect( Collectors.toMap(p -> p, p -> "Blah") );

您避免空值的過濾器是錯誤的,應該是&&。

具有 null 值的第 7 種貨幣正在通過(因為 null != "")並打破,因為 null 不能成為地圖上的鍵。

嘗試

.filter(p -> p.getCurrencyCode() != "" && p.getCurrencyCode() != null)

暫無
暫無

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

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