Java流和过滤到Map会产生错误

时间:2019-02-05 19:18:05

标签: java java-8 java-stream

我正在尝试使用Java流创建一个包含货币代码和字符串描述的地图。当我尝试添加项目1到6时,该代码有效,但是当我尝试添加item7(未初始化currencyCode参数的地方)时,出现以下错误。

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)

如何修改以下代码以过滤出未初始化currencyCode值的项目?我本以为过滤掉null应该可以解决问题,但这还行不通。

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));
    }
}

2 个答案:

答案 0 :(得分:1)

问题实际上在 distinctByKey()方法中。

发送以添加到“设置”中时,发生异常。只需将您的distinctByKey()方法更改为此。我用这种方法处理了空值。

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") );

答案 1 :(得分:0)

您为避免null的过滤器错误,应为&&。

具有null值的第7个货币正在经历(因为null!=“”)并且正在中断,因为null不能成为地图上的键。

尝试

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