1. 程式人生 > 其它 >Exception in thread "main" java.lang.IllegalStateException: Duplicate key 1

Exception in thread "main" java.lang.IllegalStateException: Duplicate key 1

Exception in thread "main" java.lang.IllegalStateException: Duplicate key 1

問題描述

原因:key重複導致的異常

錯誤di程式碼示例

public class TestCode {
public static void main(String[] args) {

List<CommonDTO> list = new ArrayList<>();
list.add( new CommonDTO(null,"2"));
list.add( new CommonDTO("1","1"));
list.add( new CommonDTO("2","3"));
list.add( new CommonDTO("1","4"));
       
//key重複導致異常
Map<String, CommonDTO> map = list.stream().collect(Collectors.toMap(CommonDTO::getKey, Function.identity()));
for (Map.Entry<String, CommonDTO> entry : map.entrySet()) {
System.out.println(entry);
}
}
}

 

/**
* 公共的資料物件
* @author lyn
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonDTO implements Serializable {

private String key;

private String value;
}

 

問題解決

解決辦法:使用過載方法,多傳入一個merge function來處理衝突

程式碼示例

Map<String, CommonDTO> map = list.stream().collect(Collectors.toMap(CommonDTO::getKey, Function.identity(), (s, a) -> a));

用法講解

格式如上,s,a變數名可以隨意起,如果->後是s,則保留最開始的,如果是a,則保留最後的

原始碼:

    /**
    * Returns a {@code Collector} that accumulates elements into a
    * {@code Map} whose keys and values are the result of applying the provided
    * mapping functions to the input elements.
    *
    * <p>If the mapped
    * keys contain duplicates (according to {@link Object#equals(Object)}),
    * the value mapping function is applied to each equal element, and the
    * results are merged using the provided merging function.
    *
    * <p>There are no guarantees on the type, mutability, serializability,
    * or thread-safety of the {@code Map} returned.
    *
    * @apiNote
    * There are multiple ways to deal with collisions between multiple elements
    * mapping to the same key. The other forms of {@code toMap} simply use
    * a merge function that throws unconditionally, but you can easily write
    * more flexible merge policies. For example, if you have a stream
    * of {@code Person}, and you want to produce a "phone book" mapping name to
    * address, but it is possible that two persons have the same name, you can
    * do as follows to gracefully deal with these collisions, and produce a
    * {@code Map} mapping names to a concatenated list of addresses:
    * <pre>{@code
    * Map<String, String> phoneBook
    *   = people.stream().collect(
    *     toMap(Person::getName,
    *           Person::getAddress,
    *           (s, a) -> s + ", " + a));
    * }</pre>
    *
    * @implNote
    * The returned {@code Collector} is not concurrent. For parallel stream
    * pipelines, the {@code combiner} function operates by merging the keys
    * from one map into another, which can be an expensive operation. If it is
    * not required that results are merged into the {@code Map} in encounter
    * order, using {@link #toConcurrentMap(Function, Function, BinaryOperator)}
    * may offer better parallel performance.
    *
    * @param <T> the type of the input elements
    * @param <K> the output type of the key mapping function
    * @param <U> the output type of the value mapping function
    * @param keyMapper a mapping function to produce keys
    * @param valueMapper a mapping function to produce values
    * @param mergeFunction a merge function, used to resolve collisions between
    *                     values associated with the same key, as supplied
    *                     to {@link Map#merge(Object, Object, BiFunction)}
    * @return a {@code Collector} which collects elements into a {@code Map}
    * whose keys are the result of applying a key mapping function to the input
    * elements, and whose values are the result of applying a value mapping
    * function to all input elements equal to the key and combining them
    * using the merge function
    *
    * @see #toMap(Function, Function)
    * @see #toMap(Function, Function, BinaryOperator, Supplier)
    * @see #toConcurrentMap(Function, Function, BinaryOperator)
    */
   public static <T, K, U>
   Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                   Function<? super T, ? extends U> valueMapper,
                                   BinaryOperator<U> mergeFunction) {
       return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
  }

 

文件參考地址1:Exception in thread "main" java.lang.IllegalStateException

文件參考地址2:https://www.cnblogs.com/han-1034683568/p/8624447.html