专栏名称: 鸭哥聊Java
回复关键字:666 ,领取免费简历模板,Java面试题,Java编程视频等。本号内容涵盖Java源码,JVM源码,Dubbo源码,Spring源码,Spring Cloud微服务架构,分布式高并发架构技术,MySQL性能调优等。
目录
相关文章推荐
钱江晚报  ·  情况属实!立即解聘! ·  昨天  
FM93交通之声  ·  撞上岩石!已致13死20伤! ·  3 天前  
Linux就该这么学  ·  运维疯传的开源神器,实现文件秒级传输? ·  3 天前  
51好读  ›  专栏  ›  鸭哥聊Java

工作8年没涨工资,悄悄面了一家涨薪 50%,但还是对老单位有感情,和领导说要是能涨薪 30%就留下,结果领导说:就你?

鸭哥聊Java  · 公众号  ·  · 2025-03-07 11:27

正文

工作八年没涨工资,这哥们终于下定决心去看看外面的世界,结果一面试,直接涨薪 50%。但他心软了,对老东家还有感情,想着只要涨 30% 就留下。结果领导一开口:“就你?涨 5% 都多了。”

这时候,他应该清醒了吧?

其实,很多人都会对自己的公司产生感情,觉得自己为公司付出了这么多年,公司是不是也该回报点什么。但事实是,公司是理性的,讲的是成本和收益,而不是情分。你觉得自己忠诚,公司可能觉得你只是廉价的劳动力。

工作是工作,感情是感情,别指望公司会因为你的付出而特别对待你。你愿意留下,是你自己的选择,公司没有义务迎合你。

所以,职场最重要的就是认清现实: 你的市场价值是由你的能力决定的,而不是你的忠诚度。 该走就走,不要犹豫,感情留给值得的人,薪资留给愿意给你开价的公司 【备注:文末可领最新资料】

今日面试题


好了,我们回归正题, 在 Java 开发过程中,我们经常需要将集合转换为 Map Stream API 提供了 Collectors.toMap() 方法来方便地完成这个操作。然而,很多开发者在使用 toMap() 时可能会遇到 NullPointerException (NPE),尤其是在 value 可能为空的情况下。

让我们从 toMap() 的内部实现开始分析这个问题。

首先, Collectors.toMap() 方法的定义如下:

public static >
Collector toMap(Function super T, ? extends K> keyMapper,
                          Function super T, ? extends U> valueMapper,
                          BinaryOperator mergeFunction,
                          Supplier mapSupplier) {
    BiConsumer accumulator
            = (map, element) -> map.merge(keyMapper.apply(element),
                                          valueMapper.apply(element), mergeFunction);
    return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
}

在这个实现中, Collectors.toMap() 调用了 Map 接口的 merge() 方法。我们再来看看 merge() 方法的具体实现:

default V merge(K key, V value,
                BiFunction super V, ? super V, ? extends V> remappingFunction)
 
{
    Objects.requireNonNull(remappingFunction);
    Objects.requireNonNull(value);
    V oldValue = get(key);
    V newValue = (oldValue == null) ? value :
                 remappingFunction.apply(oldValue, value);
    if (newValue == null) {
        remove(key);
    } else {
        put(key, newValue);
    }
    return newValue;
}

关键点在于 Objects.requireNonNull(value); 这一行代码,它会直接抛出 NullPointerException ,如果 value 为空的话。

来看一个实际的示例,假设我们有一个 Person 类,并希望将 List 转换成 Map ,以 name 作为 key phoneNumber 作为 value

class Person {
    private String name;
    private String phoneNumber;
    // 构造方法、getter 和 setter 省略
}

List bookList = new ArrayList<>();
bookList.add(new Person("jack""18163138123"));
bookList.add(new Person("martin"null));

// 这行代码会抛出 NullPointerException
bookList.stream().collect(Collectors.toMap(Person::getName, Person::getPhoneNumber));

bookList 中, martin phoneNumber 为空,所以 toMap() merge() 方法中会抛出 NullPointerException

如何避免这个问题?

1. 过滤掉 null

如果 value 可能为 null ,最简单的方式是先过滤掉 null 值:

Map bookMap = bookList.stream()
        .filter(person -> person.getPhoneNumber() != null)
        .collect(Collectors.toMap(Person::getName, Person::getPhoneNumber));

这种方法适用于不需要 null 值的场景。

2. 提供默认值

如果 value 可能为 null ,但仍然希望保留该键,可以使用 Optional 处理默认值,例如:







请到「今天看啥」查看全文