`
ColorPanda
  • 浏览: 62282 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

java8 Stream API中Collectors中toMap方法的问题以及解决

阅读更多

解决异常:java.lang.IllegalStateException: Duplicate key **

 

最近在项目中使用java8的list 转 map的时候遇到了重复值的异常:

Exception in thread "main" java.lang.IllegalStateException: Duplicate key Person@568db2f2
	at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
	at java.util.HashMap.merge(HashMap.java:1245)
	at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
	at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)

 1、写了测试类重现异常:

   在业务场景中出现重复值的时候我们希望使用新的值替换之前的值:

public static void main(String[] args) {
		Person a1= new Person("p","p1");
		Person a2= new Person("p","p2");
		Person a3= new Person("p1","p3");

		List<Person> list = new ArrayList<Person>();
		list.add(a1);
		list.add(a2);
		list.add(a3);
		//下面这句会出异常java.lang.IllegalStateException: Duplicate key
		Map<String, Person> map1 = list.stream().collect(Collectors.toMap(Person::getName , (p) -> p));		
		
	}

class Person {
	private String name;
	private String sex;

	public Person(String name, String sex) {
		super();
		this.name = name;
		this.sex = sex;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}	
}

 这段代码会抛出开头贴出来的异常:java.lang.IllegalStateException: Duplicate key **

 

总结一下:

使用Collectors.toMap方法时的两个问题: 

1、当key重复时,会抛出异常:java.lang.IllegalStateException: Duplicate key **

2、当valuenull时,会抛出异常:java.lang.NullPointerException

  

大家通常希望这个方法是可以容错的,遇到重复的key就使用后者替换,而且HashMapvalue可以是null

 

将之前出错的代码调整如下:

//下面这句会出异常java.lang.IllegalStateException: Duplicate key
Map<String, Person> map1 = list.stream().collect(Collectors.toMap(Person::getName , (p) -> p));
//修改为下面这句
Map<String, Person> map2 = list.stream().collect(Collectors.toMap(Person::getName , (p) -> p,(k,v)->v));

 

 记录一下:

//1.针对重复key的  覆盖之前的value

list.stream().collect(Collectors.toMap(Person::getName, Person::getSex,(k,v)->v));

//2.value为空,直接存放  不调用map.merge。同样适用于1(key重复的情况)

list.stream().collect(Collector.of(HashMap::new, (m,per)->m.put(per.getName(),per.getSex()), (k,v)->v, Characteristics.IDENTITY_FINISH));

//其中lambda表达式: (k,v)->v   不会被调用,但是又不能为空

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics