Java流并过滤到产生错误的映射

Java流并过滤到产生错误的映射,java,java-8,java-stream,Java,Java 8,Java Stream,我试图使用Java streams创建一个包含货币代码和字符串描述的映射。当我尝试添加项目1到6时,代码可以工作,但是当我尝试添加项目7(currencyCode参数未初始化)时,我得到以下错误 Exception in thread "main" java.lang.NullPointerException at java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011) at java.

我试图使用Java streams创建一个包含货币代码和字符串描述的映射。当我尝试添加项目1到6时,代码可以工作,但是当我尝试添加项目7(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));
    }
}
公共类测试{
公共静态void main(字符串[]args){
货币项目1=新货币();
项目1.设定货币代码(“美元”);
货币项目2=新货币();
项目2.设置货币代码(“英镑”);
货币项目3=新货币();
项目3.设置货币代码(“英镑”);
货币项目4=新货币();
第4项:设置货币代码(“AUS”);
货币项目5=新货币();
项目5.设定货币代码(“美元”);
货币项目6=新货币();
第6项:设置货币代码(“”);
货币项目7=新货币();
列表=新的ArrayList();
增加(第1项);
增加(第2项);
增加(第3项);
增加(第4项);
增加(第5项);
增加(第6项);
增加(第7项);
Map 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”);
对于(Map.Entry:distinctCurrencyCodes.entrySet()){
System.out.println(entry.getKey()+“/”+entry.getValue());
}
}
公共静态谓词distinctByKey(函数键提取器){
Set seen=ConcurrentHashMap.newKeySet();
返回t->seen.add(keydextractor.apply(t));
}
}

避免null的筛选器错误,应为&&


值为null的第七种货币正在通过(因为null!=“”),并正在中断,因为null不能是地图上的键

试一试


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

当您向外接程序集发送null时,会发生异常。只需将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);
    };
}
你可以删除这个。因此,您的过滤部分将是:

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

您发布的“错误”不是错误,它只是stacktrace的一个元素,没有向我们提供任何信息。我发现的另一个问题:
p.getCurrencyCode()!=“
-请参阅:“如何修改以下代码以筛选出未初始化currencyCode值的项目?”在
之前添加
.filter(p->p.getCurrencyCode()!=null)
。filter(distinctByKey(p->p.getCurrencyCode())
谢谢Andreas!你是对的,过滤的顺序对我来说是个问题。“而且因为null不能是映射上的键而中断”-它可以用于
HashMap
.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") );