问题1:如何将自身做为value#
Map < String , IndexMetricsTrendRowVO > rowMap = trendRows. stream ( ) . collect ( Collectors . toMap ( IndexMetricsTrendRowVO :: getDateTime , Function . identity ( ) ) ) ;
问题2:value为null报NPE #
Map < String , Field > fieldMap = allFieldsList. stream ( ) . collect ( Collectors . toMap ( Field :: getName , Function . identity ( ) ) ) ;
原因: 调用了map 的merge 方法, HashMap::merge方法会对value判断为null,默认的merge函数也会Objects.requireNonNull判断
public static < T , K , U , M extends Map < K , U > >
Collector < T , ? , M > toMap ( Function < ? super T , ? extends K > keyMapper,
Function < ? super T , ? extends U > valueMapper,
BinaryOperator < U > mergeFunction,
Supplier < M > mapSupplier) {
BiConsumer < M , T > accumulator
= ( map, element) -> map. merge ( keyMapper. apply ( element) ,
valueMapper. apply ( element) , mergeFunction) ;
return new CollectorImpl < > ( mapSupplier, accumulator, mapMerger ( mergeFunction) , CH_ID ) ;
}
@Override
public V merge ( K key, V value,
BiFunction < ? super V , ? super V , ? extends V > remappingFunction) {
if ( value == null )
throw new NullPointerException ( ) ;
. . .
}
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;
}
解决:自定义一个collect收集器,自定义mergeFunction为HashMap::putAll
Map < String , IndexMetricsRowVO > rowMap = trendRows. stream ( ) . collect ( HashMap :: new , ( map, row) -> map. put ( row. getXaxis ( ) , row) , HashMap :: putAll ) ;
问题3:toMap报java.lang.IllegalStateException: Duplicate key#
原因: 有重复的key,使用了默认的mergeFunction ,默认mergeFunction 抛出异常
public static < T , K , U >
Collector < T , ? , Map < K , U > > toMap ( Function < ? super T , ? extends K > keyMapper,
Function < ? super T , ? extends U > valueMapper) {
return toMap ( keyMapper, valueMapper, throwingMerger ( ) , HashMap :: new ) ;
}
public static < T , K , U , M extends Map < K , U > >
Collector < T , ? , M > toMap ( Function < ? super T , ? extends K > keyMapper,
Function < ? super T , ? extends U > valueMapper,
BinaryOperator < U > mergeFunction,
Supplier < M > mapSupplier) {
BiConsumer < M , T > accumulator
= ( map, element) -> map. merge ( keyMapper. apply ( element) ,
valueMapper. apply ( element) , mergeFunction) ;
return new CollectorImpl < > ( mapSupplier, accumulator, mapMerger ( mergeFunction) , CH_ID ) ;
}
@Override
public V merge ( K key, V value,
BiFunction < ? super V , ? super V , ? extends V > remappingFunction) {
if ( value == null )
throw new NullPointerException ( ) ;
if ( remappingFunction == null )
throw new NullPointerException ( ) ;
. . . . . .
if ( old != null ) {
V v;
if ( old. value != null )
v = remappingFunction. apply ( old. value, value) ;
else
v = value;
if ( v != null ) {
old. value = v;
afterNodeAccess ( old) ;
}
else
removeNode ( hash, key, null , false , true ) ;
return v;
}
. . . . . .
}
private static < T > BinaryOperator < T > throwingMerger ( ) {
return ( u, v) -> { throw new IllegalStateException ( String . format ( "Duplicate key %s" , u) ) ; } ;
}
解决: 参照问题2 ,自定义mergeFunction
问题4:使用其他类型的List, Set, Map#
List < String > list = strings. stream ( ) . collect ( Collectors . toCollection ( LinkedList :: new ) ) ;
Set < String > set = sets. stream ( ) . collect ( Collectors . toCollection ( TreeSet :: new ) ) ;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程