Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
ad59a26e
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
ad59a26e
编写于
4月 16, 2013
作者:
C
chegar
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
29a714c1
6019b1d8
变更
6
展开全部
隐藏空白更改
内联
并排
Showing
6 changed file
with
2097 addition
and
51 deletion
+2097
-51
src/share/classes/java/util/Collections.java
src/share/classes/java/util/Collections.java
+333
-18
src/share/classes/java/util/HashMap.java
src/share/classes/java/util/HashMap.java
+271
-5
src/share/classes/java/util/Hashtable.java
src/share/classes/java/util/Hashtable.java
+259
-16
src/share/classes/java/util/Map.java
src/share/classes/java/util/Map.java
+614
-1
src/share/classes/java/util/concurrent/ConcurrentMap.java
src/share/classes/java/util/concurrent/ConcurrentMap.java
+26
-11
test/java/util/Map/Defaults.java
test/java/util/Map/Defaults.java
+594
-0
未找到文件。
src/share/classes/java/util/Collections.java
浏览文件 @
ad59a26e
...
...
@@ -28,6 +28,9 @@ import java.io.Serializable;
import
java.io.ObjectOutputStream
;
import
java.io.IOException
;
import
java.lang.reflect.Array
;
import
java.util.function.BiConsumer
;
import
java.util.function.BiFunction
;
import
java.util.function.Function
;
/**
* This class consists exclusively of static methods that operate on or return
...
...
@@ -264,8 +267,7 @@ public class Collections {
}
private
static
<
T
>
int
indexedBinarySearch
(
List
<?
extends
Comparable
<?
super
T
>>
list
,
T
key
)
{
int
indexedBinarySearch
(
List
<?
extends
Comparable
<?
super
T
>>
list
,
T
key
)
{
int
low
=
0
;
int
high
=
list
.
size
()-
1
;
...
...
@@ -441,21 +443,21 @@ public class Collections {
/**
* Randomly permutes the specified list using a default source of
* randomness. All permutations occur with approximately equal
* likelihood.
<p>
* likelihood.
*
* The hedge "approximately" is used in the foregoing description because
*
<p>
The hedge "approximately" is used in the foregoing description because
* default source of randomness is only approximately an unbiased source
* of independently chosen bits. If it were a perfect source of randomly
* chosen bits, then the algorithm would choose permutations with perfect
* uniformity.
<p>
* uniformity.
*
*
This implementation traverses the list backwards, from the last elemen
t
*
up to the second, repeatedly swapping a randomly selected element into
* the "current position". Elements are randomly selected from the
*
<p>This implementation traverses the list backwards, from the las
t
*
element up to the second, repeatedly swapping a randomly selected element
*
into
the "current position". Elements are randomly selected from the
* portion of the list that runs from the first element to the current
* position, inclusive.
<p>
* position, inclusive.
*
* This method runs in linear time. If the specified list does not
*
<p>
This method runs in linear time. If the specified list does not
* implement the {@link RandomAccess} interface and is large, this
* implementation dumps the specified list into an array before shuffling
* it, and dumps the shuffled array back into the list. This avoids the
...
...
@@ -469,9 +471,10 @@ public class Collections {
public
static
void
shuffle
(
List
<?>
list
)
{
Random
rnd
=
r
;
if
(
rnd
==
null
)
r
=
rnd
=
new
Random
();
r
=
rnd
=
new
Random
();
// harmless race.
shuffle
(
list
,
rnd
);
}
private
static
Random
r
;
/**
...
...
@@ -1391,6 +1394,67 @@ public class Collections {
public
int
hashCode
()
{
return
m
.
hashCode
();}
public
String
toString
()
{
return
m
.
toString
();}
// Override default methods in Map
@Override
@SuppressWarnings
(
"unchecked"
)
public
V
getOrDefault
(
Object
k
,
V
defaultValue
)
{
// Safe cast as we don't change the value
return
((
Map
<
K
,
V
>)
m
).
getOrDefault
(
k
,
defaultValue
);
}
@Override
public
void
forEach
(
BiConsumer
<?
super
K
,
?
super
V
>
action
)
{
m
.
forEach
(
action
);
}
@Override
public
void
replaceAll
(
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
function
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
putIfAbsent
(
K
key
,
V
value
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
boolean
remove
(
Object
key
,
Object
value
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
boolean
replace
(
K
key
,
V
oldValue
,
V
newValue
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
replace
(
K
key
,
V
value
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
computeIfAbsent
(
K
key
,
Function
<?
super
K
,
?
extends
V
>
mappingFunction
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
computeIfPresent
(
K
key
,
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
compute
(
K
key
,
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
merge
(
K
key
,
V
value
,
BiFunction
<?
super
V
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
throw
new
UnsupportedOperationException
();
}
/**
* We need this class in addition to UnmodifiableSet as
* Map.Entries themselves permit modification of the backing Map
...
...
@@ -1590,9 +1654,9 @@ public class Collections {
* </pre>
* Failure to follow this advice may result in non-deterministic behavior.
*
* <p>The returned collection does <i>not</i> pass the
<tt>hashCode</tt>
* and
<tt>equals</tt>
operations through to the backing collection, but
* relies on
<tt>Object</tt>
's equals and hashCode methods. This is
* <p>The returned collection does <i>not</i> pass the
{@code hashCode}
* and
{@code equals}
operations through to the backing collection, but
* relies on
{@code Object}
's equals and hashCode methods. This is
* necessary to preserve the contracts of these operations in the case
* that the backing collection is a set or a list.<p>
*
...
...
@@ -2107,6 +2171,57 @@ public class Collections {
public
String
toString
()
{
synchronized
(
mutex
)
{
return
m
.
toString
();}
}
// Override default methods in Map
@Override
public
V
getOrDefault
(
Object
k
,
V
defaultValue
)
{
synchronized
(
mutex
)
{
return
m
.
getOrDefault
(
k
,
defaultValue
);}
}
@Override
public
void
forEach
(
BiConsumer
<?
super
K
,
?
super
V
>
action
)
{
synchronized
(
mutex
)
{
m
.
forEach
(
action
);}
}
@Override
public
void
replaceAll
(
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
function
)
{
synchronized
(
mutex
)
{
m
.
replaceAll
(
function
);}
}
@Override
public
V
putIfAbsent
(
K
key
,
V
value
)
{
synchronized
(
mutex
)
{
return
m
.
putIfAbsent
(
key
,
value
);}
}
@Override
public
boolean
remove
(
Object
key
,
Object
value
)
{
synchronized
(
mutex
)
{
return
m
.
remove
(
key
,
value
);}
}
@Override
public
boolean
replace
(
K
key
,
V
oldValue
,
V
newValue
)
{
synchronized
(
mutex
)
{
return
m
.
replace
(
key
,
oldValue
,
newValue
);}
}
@Override
public
V
replace
(
K
key
,
V
value
)
{
synchronized
(
mutex
)
{
return
m
.
replace
(
key
,
value
);}
}
@Override
public
V
computeIfAbsent
(
K
key
,
Function
<?
super
K
,
?
extends
V
>
mappingFunction
)
{
synchronized
(
mutex
)
{
return
m
.
computeIfAbsent
(
key
,
mappingFunction
);}
}
@Override
public
V
computeIfPresent
(
K
key
,
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
synchronized
(
mutex
)
{
return
m
.
computeIfPresent
(
key
,
remappingFunction
);}
}
@Override
public
V
compute
(
K
key
,
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
synchronized
(
mutex
)
{
return
m
.
compute
(
key
,
remappingFunction
);}
}
@Override
public
V
merge
(
K
key
,
V
value
,
BiFunction
<?
super
V
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
synchronized
(
mutex
)
{
return
m
.
merge
(
key
,
value
,
remappingFunction
);}
}
private
void
writeObject
(
ObjectOutputStream
s
)
throws
IOException
{
synchronized
(
mutex
)
{
s
.
defaultWriteObject
();}
}
...
...
@@ -2326,6 +2441,8 @@ public class Collections {
}
public
Iterator
<
E
>
iterator
()
{
// JDK-6363904 - unwrapped iterator could be typecast to
// ListIterator with unsafe set()
final
Iterator
<
E
>
it
=
c
.
iterator
();
return
new
Iterator
<
E
>()
{
public
boolean
hasNext
()
{
return
it
.
hasNext
();
}
...
...
@@ -2652,7 +2769,7 @@ public class Collections {
public
List
<
E
>
subList
(
int
fromIndex
,
int
toIndex
)
{
return
new
CheckedRandomAccessList
<>(
list
.
subList
(
fromIndex
,
toIndex
),
type
);
list
.
subList
(
fromIndex
,
toIndex
),
type
);
}
}
...
...
@@ -2717,14 +2834,24 @@ public class Collections {
throw
new
ClassCastException
(
badValueMsg
(
value
));
}
private
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
typeCheck
(
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
func
)
{
Objects
.
requireNonNull
(
func
);
return
(
k
,
v
)
->
{
V
newValue
=
func
.
apply
(
k
,
v
);
typeCheck
(
k
,
newValue
);
return
newValue
;
};
}
private
String
badKeyMsg
(
Object
key
)
{
return
"Attempt to insert "
+
key
.
getClass
()
+
" key into map with key type "
+
keyType
;
" key into map with key type "
+
keyType
;
}
private
String
badValueMsg
(
Object
value
)
{
return
"Attempt to insert "
+
value
.
getClass
()
+
" value into map with value type "
+
valueType
;
" value into map with value type "
+
valueType
;
}
CheckedMap
(
Map
<
K
,
V
>
m
,
Class
<
K
>
keyType
,
Class
<
V
>
valueType
)
{
...
...
@@ -2768,7 +2895,7 @@ public class Collections {
Object
v
=
e
.
getValue
();
typeCheck
(
k
,
v
);
checked
.
add
(
new
AbstractMap
.
SimpleImmutableEntry
<>((
K
)
k
,
(
V
)
v
));
new
AbstractMap
.
SimpleImmutableEntry
<>((
K
)
k
,
(
V
)
v
));
}
for
(
Map
.
Entry
<
K
,
V
>
e
:
checked
)
m
.
put
(
e
.
getKey
(),
e
.
getValue
());
...
...
@@ -2782,6 +2909,74 @@ public class Collections {
return
entrySet
;
}
// Override default methods in Map
@Override
public
void
forEach
(
BiConsumer
<?
super
K
,
?
super
V
>
action
)
{
m
.
forEach
(
action
);
}
@Override
public
void
replaceAll
(
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
function
)
{
m
.
replaceAll
(
typeCheck
(
function
));
}
@Override
public
V
putIfAbsent
(
K
key
,
V
value
)
{
typeCheck
(
key
,
value
);
return
m
.
putIfAbsent
(
key
,
value
);
}
@Override
public
boolean
remove
(
Object
key
,
Object
value
)
{
return
m
.
remove
(
key
,
value
);
}
@Override
public
boolean
replace
(
K
key
,
V
oldValue
,
V
newValue
)
{
typeCheck
(
key
,
newValue
);
return
m
.
replace
(
key
,
oldValue
,
newValue
);
}
@Override
public
V
replace
(
K
key
,
V
value
)
{
typeCheck
(
key
,
value
);
return
m
.
replace
(
key
,
value
);
}
@Override
public
V
computeIfAbsent
(
K
key
,
Function
<?
super
K
,
?
extends
V
>
mappingFunction
)
{
Objects
.
requireNonNull
(
mappingFunction
);
return
m
.
computeIfAbsent
(
key
,
k
->
{
V
value
=
mappingFunction
.
apply
(
k
);
typeCheck
(
k
,
value
);
return
value
;
});
}
@Override
public
V
computeIfPresent
(
K
key
,
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
return
m
.
computeIfPresent
(
key
,
typeCheck
(
remappingFunction
));
}
@Override
public
V
compute
(
K
key
,
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
return
m
.
compute
(
key
,
typeCheck
(
remappingFunction
));
}
@Override
public
V
merge
(
K
key
,
V
value
,
BiFunction
<?
super
V
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
Objects
.
requireNonNull
(
remappingFunction
);
return
m
.
merge
(
key
,
value
,
(
v1
,
v2
)
->
{
V
newValue
=
remappingFunction
.
apply
(
v1
,
v2
);
typeCheck
(
null
,
newValue
);
return
newValue
;
});
}
/**
* We need this class in addition to CheckedSet as Map.Entry permits
* modification of the backing Map via the setValue operation. This
...
...
@@ -3456,6 +3651,67 @@ public class Collections {
public
int
hashCode
()
{
return
0
;}
// Override default methods in Map
@Override
@SuppressWarnings
(
"unchecked"
)
public
V
getOrDefault
(
Object
k
,
V
defaultValue
)
{
return
defaultValue
;
}
@Override
public
void
forEach
(
BiConsumer
<?
super
K
,
?
super
V
>
action
)
{
Objects
.
requireNonNull
(
action
);
}
@Override
public
void
replaceAll
(
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
function
)
{
Objects
.
requireNonNull
(
function
);
}
@Override
public
V
putIfAbsent
(
K
key
,
V
value
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
boolean
remove
(
Object
key
,
Object
value
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
boolean
replace
(
K
key
,
V
oldValue
,
V
newValue
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
replace
(
K
key
,
V
value
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
computeIfAbsent
(
K
key
,
Function
<?
super
K
,
?
extends
V
>
mappingFunction
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
computeIfPresent
(
K
key
,
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
compute
(
K
key
,
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
merge
(
K
key
,
V
value
,
BiFunction
<?
super
V
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
throw
new
UnsupportedOperationException
();
}
// Preserves singleton property
private
Object
readResolve
()
{
return
EMPTY_MAP
;
...
...
@@ -3619,6 +3875,65 @@ public class Collections {
return
values
;
}
// Override default methods in Map
@Override
public
V
getOrDefault
(
Object
key
,
V
defaultValue
)
{
return
eq
(
key
,
k
)
?
v
:
defaultValue
;
}
@Override
public
void
forEach
(
BiConsumer
<?
super
K
,
?
super
V
>
action
)
{
action
.
accept
(
k
,
v
);
}
@Override
public
void
replaceAll
(
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
function
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
putIfAbsent
(
K
key
,
V
value
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
boolean
remove
(
Object
key
,
Object
value
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
boolean
replace
(
K
key
,
V
oldValue
,
V
newValue
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
replace
(
K
key
,
V
value
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
computeIfAbsent
(
K
key
,
Function
<?
super
K
,
?
extends
V
>
mappingFunction
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
computeIfPresent
(
K
key
,
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
compute
(
K
key
,
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
V
merge
(
K
key
,
V
value
,
BiFunction
<?
super
V
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
throw
new
UnsupportedOperationException
();
}
}
// Miscellaneous
...
...
src/share/classes/java/util/HashMap.java
浏览文件 @
ad59a26e
/*
* Copyright (c) 1997, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -24,7 +24,11 @@
*/
package
java.util
;
import
java.io.*
;
import
java.util.function.Consumer
;
import
java.util.function.BiFunction
;
import
java.util.function.Function
;
/**
* Hash table based implementation of the <tt>Map</tt> interface. This
...
...
@@ -376,6 +380,13 @@ public class HashMap<K,V>
return
null
==
entry
?
null
:
entry
.
getValue
();
}
@Override
public
V
getOrDefault
(
Object
key
,
V
defaultValue
)
{
Entry
<
K
,
V
>
entry
=
getEntry
(
key
);
return
(
entry
==
null
)
?
defaultValue
:
entry
.
getValue
();
}
/**
* Returns <tt>true</tt> if this map contains a mapping for the
* specified key.
...
...
@@ -603,6 +614,261 @@ public class HashMap<K,V>
return
(
e
==
null
?
null
:
e
.
value
);
}
// optimized implementations of default methods in Map
@Override
public
V
putIfAbsent
(
K
key
,
V
value
)
{
if
(
table
==
EMPTY_TABLE
)
{
inflateTable
(
threshold
);
}
int
hash
=
(
key
==
null
)
?
0
:
hash
(
key
);
int
i
=
indexFor
(
hash
,
table
.
length
);
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
e
=
(
Entry
<
K
,
V
>)
table
[
i
];
for
(;
e
!=
null
;
e
=
e
.
next
)
{
if
(
e
.
hash
==
hash
&&
Objects
.
equals
(
e
.
key
,
key
))
{
if
(
e
.
value
!=
null
)
{
return
e
.
value
;
}
e
.
value
=
value
;
modCount
++;
e
.
recordAccess
(
this
);
return
null
;
}
}
modCount
++;
addEntry
(
hash
,
key
,
value
,
i
);
return
null
;
}
@Override
public
boolean
remove
(
Object
key
,
Object
value
)
{
if
(
isEmpty
())
{
return
false
;
}
int
hash
=
(
key
==
null
)
?
0
:
hash
(
key
);
int
i
=
indexFor
(
hash
,
table
.
length
);
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
prev
=
(
Entry
<
K
,
V
>)
table
[
i
];
Entry
<
K
,
V
>
e
=
prev
;
while
(
e
!=
null
)
{
Entry
<
K
,
V
>
next
=
e
.
next
;
if
(
e
.
hash
==
hash
&&
Objects
.
equals
(
e
.
key
,
key
))
{
if
(!
Objects
.
equals
(
e
.
value
,
value
))
{
return
false
;
}
modCount
++;
size
--;
if
(
prev
==
e
)
table
[
i
]
=
next
;
else
prev
.
next
=
next
;
e
.
recordRemoval
(
this
);
return
true
;
}
prev
=
e
;
e
=
next
;
}
return
false
;
}
@Override
public
boolean
replace
(
K
key
,
V
oldValue
,
V
newValue
)
{
if
(
isEmpty
())
{
return
false
;
}
int
hash
=
(
key
==
null
)
?
0
:
hash
(
key
);
int
i
=
indexFor
(
hash
,
table
.
length
);
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
e
=
(
Entry
<
K
,
V
>)
table
[
i
];
for
(;
e
!=
null
;
e
=
e
.
next
)
{
if
(
e
.
hash
==
hash
&&
Objects
.
equals
(
e
.
key
,
key
)
&&
Objects
.
equals
(
e
.
value
,
oldValue
))
{
e
.
value
=
newValue
;
e
.
recordAccess
(
this
);
return
true
;
}
}
return
false
;
}
@Override
public
V
replace
(
K
key
,
V
value
)
{
if
(
isEmpty
())
{
return
null
;
}
int
hash
=
(
key
==
null
)
?
0
:
hash
(
key
);
int
i
=
indexFor
(
hash
,
table
.
length
);
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
e
=
(
Entry
<
K
,
V
>)
table
[
i
];
for
(;
e
!=
null
;
e
=
e
.
next
)
{
if
(
e
.
hash
==
hash
&&
Objects
.
equals
(
e
.
key
,
key
))
{
V
oldValue
=
e
.
value
;
e
.
value
=
value
;
e
.
recordAccess
(
this
);
return
oldValue
;
}
}
return
null
;
}
@Override
public
V
computeIfAbsent
(
K
key
,
Function
<?
super
K
,
?
extends
V
>
mappingFunction
)
{
if
(
table
==
EMPTY_TABLE
)
{
inflateTable
(
threshold
);
}
int
hash
=
(
key
==
null
)
?
0
:
hash
(
key
);
int
i
=
indexFor
(
hash
,
table
.
length
);
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
e
=
(
Entry
<
K
,
V
>)
table
[
i
];
for
(;
e
!=
null
;
e
=
e
.
next
)
{
if
(
e
.
hash
==
hash
&&
Objects
.
equals
(
e
.
key
,
key
))
{
V
oldValue
=
e
.
value
;
return
oldValue
==
null
?
(
e
.
value
=
mappingFunction
.
apply
(
key
))
:
oldValue
;
}
}
V
newValue
=
mappingFunction
.
apply
(
key
);
if
(
newValue
!=
null
)
{
modCount
++;
addEntry
(
hash
,
key
,
newValue
,
i
);
}
return
newValue
;
}
@Override
public
V
computeIfPresent
(
K
key
,
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
if
(
isEmpty
())
{
return
null
;
}
int
hash
=
(
key
==
null
)
?
0
:
hash
(
key
);
int
i
=
indexFor
(
hash
,
table
.
length
);
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
prev
=
(
Entry
<
K
,
V
>)
table
[
i
];
Entry
<
K
,
V
>
e
=
prev
;
while
(
e
!=
null
)
{
Entry
<
K
,
V
>
next
=
e
.
next
;
if
(
e
.
hash
==
hash
&&
Objects
.
equals
(
e
.
key
,
key
))
{
V
oldValue
=
e
.
value
;
if
(
oldValue
==
null
)
break
;
V
newValue
=
remappingFunction
.
apply
(
key
,
oldValue
);
modCount
++;
if
(
newValue
==
null
)
{
size
--;
if
(
prev
==
e
)
table
[
i
]
=
next
;
else
prev
.
next
=
next
;
e
.
recordRemoval
(
this
);
}
else
{
e
.
value
=
newValue
;
e
.
recordAccess
(
this
);
}
return
newValue
;
}
prev
=
e
;
e
=
next
;
}
return
null
;
}
@Override
public
V
compute
(
K
key
,
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
if
(
table
==
EMPTY_TABLE
)
{
inflateTable
(
threshold
);
}
int
hash
=
(
key
==
null
)
?
0
:
hash
(
key
);
int
i
=
indexFor
(
hash
,
table
.
length
);
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
prev
=
(
Entry
<
K
,
V
>)
table
[
i
];
Entry
<
K
,
V
>
e
=
prev
;
while
(
e
!=
null
)
{
Entry
<
K
,
V
>
next
=
e
.
next
;
if
(
e
.
hash
==
hash
&&
Objects
.
equals
(
e
.
key
,
key
))
{
V
oldValue
=
e
.
value
;
V
newValue
=
remappingFunction
.
apply
(
key
,
oldValue
);
if
(
newValue
!=
oldValue
)
{
modCount
++;
if
(
newValue
==
null
)
{
size
--;
if
(
prev
==
e
)
table
[
i
]
=
next
;
else
prev
.
next
=
next
;
e
.
recordRemoval
(
this
);
}
else
{
e
.
value
=
newValue
;
e
.
recordAccess
(
this
);
}
}
return
newValue
;
}
prev
=
e
;
e
=
next
;
}
V
newValue
=
remappingFunction
.
apply
(
key
,
null
);
if
(
newValue
!=
null
)
{
modCount
++;
addEntry
(
hash
,
key
,
newValue
,
i
);
}
return
newValue
;
}
@Override
public
V
merge
(
K
key
,
V
value
,
BiFunction
<?
super
V
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
if
(
table
==
EMPTY_TABLE
)
{
inflateTable
(
threshold
);
}
int
hash
=
(
key
==
null
)
?
0
:
hash
(
key
);
int
i
=
indexFor
(
hash
,
table
.
length
);
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
prev
=
(
Entry
<
K
,
V
>)
table
[
i
];
Entry
<
K
,
V
>
e
=
prev
;
while
(
e
!=
null
)
{
Entry
<
K
,
V
>
next
=
e
.
next
;
if
(
e
.
hash
==
hash
&&
Objects
.
equals
(
e
.
key
,
key
))
{
V
oldValue
=
e
.
value
;
V
newValue
=
remappingFunction
.
apply
(
oldValue
,
value
);
modCount
++;
if
(
newValue
==
null
)
{
size
--;
if
(
prev
==
e
)
table
[
i
]
=
next
;
else
prev
.
next
=
next
;
e
.
recordRemoval
(
this
);
}
else
{
e
.
value
=
newValue
;
e
.
recordAccess
(
this
);
}
return
newValue
;
}
prev
=
e
;
e
=
next
;
}
if
(
value
!=
null
)
{
modCount
++;
addEntry
(
hash
,
key
,
value
,
i
);
}
return
value
;
}
// end of optimized implementations of default methods in Map
/**
* Removes and returns the entry associated with the specified key
* in the HashMap. Returns null if the HashMap contains no mapping
...
...
@@ -697,8 +963,8 @@ public class HashMap<K,V>
return
containsNullValue
();
Entry
<?,?>[]
tab
=
table
;
for
(
int
i
=
0
;
i
<
tab
.
length
;
i
++)
for
(
Entry
<?,?>
e
=
tab
[
i
]
;
e
!=
null
;
e
=
e
.
next
)
for
(
int
i
=
0
;
i
<
tab
.
length
;
i
++)
for
(
Entry
<?,?>
e
=
tab
[
i
]
;
e
!=
null
;
e
=
e
.
next
)
if
(
value
.
equals
(
e
.
value
))
return
true
;
return
false
;
...
...
@@ -709,8 +975,8 @@ public class HashMap<K,V>
*/
private
boolean
containsNullValue
()
{
Entry
<?,?>[]
tab
=
table
;
for
(
int
i
=
0
;
i
<
tab
.
length
;
i
++)
for
(
Entry
<?,?>
e
=
tab
[
i
]
;
e
!=
null
;
e
=
e
.
next
)
for
(
int
i
=
0
;
i
<
tab
.
length
;
i
++)
for
(
Entry
<?,?>
e
=
tab
[
i
]
;
e
!=
null
;
e
=
e
.
next
)
if
(
e
.
value
==
null
)
return
true
;
return
false
;
...
...
src/share/classes/java/util/Hashtable.java
浏览文件 @
ad59a26e
/*
* Copyright (c) 1994, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -24,7 +24,11 @@
*/
package
java.util
;
import
java.io.*
;
import
java.util.function.BiConsumer
;
import
java.util.function.Function
;
import
java.util.function.BiFunction
;
/**
* This class implements a hash table, which maps keys to values. Any
...
...
@@ -455,6 +459,26 @@ public class Hashtable<K,V>
}
}
private
void
addEntry
(
int
hash
,
K
key
,
V
value
,
int
index
)
{
modCount
++;
Entry
<?,?>
tab
[]
=
table
;
if
(
count
>=
threshold
)
{
// Rehash the table if the threshold is exceeded
rehash
();
tab
=
table
;
hash
=
hash
(
key
);
index
=
(
hash
&
0x7FFFFFFF
)
%
tab
.
length
;
}
// Creates the new entry.
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
e
=
(
Entry
<
K
,
V
>)
tab
[
index
];
tab
[
index
]
=
new
Entry
<>(
hash
,
key
,
value
,
e
);
count
++;
}
/**
* Maps the specified <code>key</code> to the specified
* <code>value</code> in this hashtable. Neither the key nor the
...
...
@@ -492,21 +516,7 @@ public class Hashtable<K,V>
}
}
modCount
++;
if
(
count
>=
threshold
)
{
// Rehash the table if the threshold is exceeded
rehash
();
tab
=
table
;
hash
=
hash
(
key
);
index
=
(
hash
&
0x7FFFFFFF
)
%
tab
.
length
;
}
// Creates the new entry.
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
e
=
(
Entry
<
K
,
V
>)
tab
[
index
];
tab
[
index
]
=
new
Entry
<>(
hash
,
key
,
value
,
e
);
count
++;
addEntry
(
hash
,
key
,
value
,
index
);
return
null
;
}
...
...
@@ -892,6 +902,239 @@ public class Hashtable<K,V>
return
h
;
}
@Override
public
synchronized
V
getOrDefault
(
Object
key
,
V
defaultValue
)
{
V
result
=
get
(
key
);
return
(
null
==
result
)
?
defaultValue
:
result
;
}
@Override
public
synchronized
void
forEach
(
BiConsumer
<?
super
K
,
?
super
V
>
action
)
{
Objects
.
requireNonNull
(
action
);
// explicit check required in case
// table is empty.
Entry
<?,?>[]
tab
=
table
;
for
(
Entry
<?,?>
entry
:
tab
)
{
while
(
entry
!=
null
)
{
action
.
accept
((
K
)
entry
.
key
,
(
V
)
entry
.
value
);
entry
=
entry
.
next
;
}
}
}
@Override
public
synchronized
void
replaceAll
(
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
function
)
{
Map
.
super
.
replaceAll
(
function
);
}
@Override
public
synchronized
V
putIfAbsent
(
K
key
,
V
value
)
{
Objects
.
requireNonNull
(
value
);
// Makes sure the key is not already in the hashtable.
Entry
<?,?>
tab
[]
=
table
;
int
hash
=
hash
(
key
);
int
index
=
(
hash
&
0x7FFFFFFF
)
%
tab
.
length
;
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
entry
=
(
Entry
<
K
,
V
>)
tab
[
index
];
for
(;
entry
!=
null
;
entry
=
entry
.
next
)
{
if
((
entry
.
hash
==
hash
)
&&
entry
.
key
.
equals
(
key
))
{
V
old
=
entry
.
value
;
if
(
old
==
null
)
{
entry
.
value
=
value
;
}
return
old
;
}
}
addEntry
(
hash
,
key
,
value
,
index
);
return
null
;
}
@Override
public
synchronized
boolean
remove
(
Object
key
,
Object
value
)
{
Objects
.
requireNonNull
(
value
);
Entry
<?,?>
tab
[]
=
table
;
int
hash
=
hash
(
key
);
int
index
=
(
hash
&
0x7FFFFFFF
)
%
tab
.
length
;
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
e
=
(
Entry
<
K
,
V
>)
tab
[
index
];
for
(
Entry
<
K
,
V
>
prev
=
null
;
e
!=
null
;
prev
=
e
,
e
=
e
.
next
)
{
if
((
e
.
hash
==
hash
)
&&
e
.
key
.
equals
(
key
)
&&
e
.
value
.
equals
(
value
))
{
modCount
++;
if
(
prev
!=
null
)
{
prev
.
next
=
e
.
next
;
}
else
{
tab
[
index
]
=
e
.
next
;
}
count
--;
e
.
value
=
null
;
return
true
;
}
}
return
false
;
}
@Override
public
synchronized
boolean
replace
(
K
key
,
V
oldValue
,
V
newValue
)
{
Entry
<?,?>
tab
[]
=
table
;
int
hash
=
hash
(
key
);
int
index
=
(
hash
&
0x7FFFFFFF
)
%
tab
.
length
;
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
e
=
(
Entry
<
K
,
V
>)
tab
[
index
];
for
(;
e
!=
null
;
e
=
e
.
next
)
{
if
((
e
.
hash
==
hash
)
&&
e
.
key
.
equals
(
key
))
{
if
(
e
.
value
.
equals
(
oldValue
))
{
e
.
value
=
newValue
;
return
true
;
}
else
{
return
false
;
}
}
}
return
false
;
}
@Override
public
synchronized
V
replace
(
K
key
,
V
value
)
{
Entry
<?,?>
tab
[]
=
table
;
int
hash
=
hash
(
key
);
int
index
=
(
hash
&
0x7FFFFFFF
)
%
tab
.
length
;
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
e
=
(
Entry
<
K
,
V
>)
tab
[
index
];
for
(;
e
!=
null
;
e
=
e
.
next
)
{
if
((
e
.
hash
==
hash
)
&&
e
.
key
.
equals
(
key
))
{
V
oldValue
=
e
.
value
;
e
.
value
=
value
;
return
oldValue
;
}
}
return
null
;
}
@Override
public
synchronized
V
computeIfAbsent
(
K
key
,
Function
<?
super
K
,
?
extends
V
>
mappingFunction
)
{
Objects
.
requireNonNull
(
mappingFunction
);
Entry
<?,?>
tab
[]
=
table
;
int
hash
=
hash
(
key
);
int
index
=
(
hash
&
0x7FFFFFFF
)
%
tab
.
length
;
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
e
=
(
Entry
<
K
,
V
>)
tab
[
index
];
for
(;
e
!=
null
;
e
=
e
.
next
)
{
if
(
e
.
hash
==
hash
&&
e
.
key
.
equals
(
key
))
{
// Hashtable not accept null value
return
e
.
value
;
}
}
V
newValue
=
mappingFunction
.
apply
(
key
);
if
(
newValue
!=
null
)
{
addEntry
(
hash
,
key
,
newValue
,
index
);
}
return
newValue
;
}
@Override
public
V
computeIfPresent
(
K
key
,
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
Objects
.
requireNonNull
(
remappingFunction
);
Entry
<?,?>
tab
[]
=
table
;
int
hash
=
hash
(
key
);
int
index
=
(
hash
&
0x7FFFFFFF
)
%
tab
.
length
;
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
e
=
(
Entry
<
K
,
V
>)
tab
[
index
];
for
(
Entry
<
K
,
V
>
prev
=
null
;
e
!=
null
;
prev
=
e
,
e
=
e
.
next
)
{
if
(
e
.
hash
==
hash
&&
e
.
key
.
equals
(
key
))
{
V
newValue
=
remappingFunction
.
apply
(
key
,
e
.
value
);
if
(
newValue
==
null
)
{
modCount
++;
if
(
prev
!=
null
)
{
prev
.
next
=
e
.
next
;
}
else
{
tab
[
index
]
=
e
.
next
;
}
count
--;
}
else
{
e
.
value
=
newValue
;
}
return
newValue
;
}
}
return
null
;
}
@Override
public
V
compute
(
K
key
,
BiFunction
<?
super
K
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
Objects
.
requireNonNull
(
remappingFunction
);
Entry
<?,?>
tab
[]
=
table
;
int
hash
=
hash
(
key
);
int
index
=
(
hash
&
0x7FFFFFFF
)
%
tab
.
length
;
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
e
=
(
Entry
<
K
,
V
>)
tab
[
index
];
for
(
Entry
<
K
,
V
>
prev
=
null
;
e
!=
null
;
prev
=
e
,
e
=
e
.
next
)
{
if
(
e
.
hash
==
hash
&&
Objects
.
equals
(
e
.
key
,
key
))
{
V
newValue
=
remappingFunction
.
apply
(
key
,
e
.
value
);
if
(
newValue
==
null
)
{
modCount
++;
if
(
prev
!=
null
)
{
prev
.
next
=
e
.
next
;
}
else
{
tab
[
index
]
=
e
.
next
;
}
count
--;
}
else
{
e
.
value
=
newValue
;
}
return
newValue
;
}
}
V
newValue
=
remappingFunction
.
apply
(
key
,
null
);
if
(
newValue
!=
null
)
{
addEntry
(
hash
,
key
,
newValue
,
index
);
}
return
newValue
;
}
@Override
public
V
merge
(
K
key
,
V
value
,
BiFunction
<?
super
V
,
?
super
V
,
?
extends
V
>
remappingFunction
)
{
Objects
.
requireNonNull
(
remappingFunction
);
Entry
<?,?>
tab
[]
=
table
;
int
hash
=
hash
(
key
);
int
index
=
(
hash
&
0x7FFFFFFF
)
%
tab
.
length
;
@SuppressWarnings
(
"unchecked"
)
Entry
<
K
,
V
>
e
=
(
Entry
<
K
,
V
>)
tab
[
index
];
for
(
Entry
<
K
,
V
>
prev
=
null
;
e
!=
null
;
prev
=
e
,
e
=
e
.
next
)
{
if
(
e
.
hash
==
hash
&&
e
.
key
.
equals
(
key
))
{
V
newValue
=
remappingFunction
.
apply
(
e
.
value
,
value
);
if
(
newValue
==
null
)
{
modCount
++;
if
(
prev
!=
null
)
{
prev
.
next
=
e
.
next
;
}
else
{
tab
[
index
]
=
e
.
next
;
}
count
--;
}
else
{
e
.
value
=
newValue
;
}
return
newValue
;
}
}
if
(
value
!=
null
)
{
addEntry
(
hash
,
key
,
value
,
index
);
}
return
value
;
}
/**
* Save the state of the Hashtable to a stream (i.e., serialize it).
*
...
...
src/share/classes/java/util/Map.java
浏览文件 @
ad59a26e
此差异已折叠。
点击以展开。
src/share/classes/java/util/concurrent/ConcurrentMap.java
浏览文件 @
ad59a26e
...
...
@@ -38,7 +38,7 @@ import java.util.Map;
/**
* A {@link java.util.Map} providing additional atomic
*
<tt>putIfAbsent</tt>, <tt>remove</tt>, and <tt>replace</tt>
methods.
*
{@code putIfAbsent}, {@code remove}, and {@code replace}
methods.
*
* <p>Memory consistency effects: As with other concurrent
* collections, actions in a thread prior to placing an object into a
...
...
@@ -57,6 +57,21 @@ import java.util.Map;
* @param <V> the type of mapped values
*/
public
interface
ConcurrentMap
<
K
,
V
>
extends
Map
<
K
,
V
>
{
/**
* {@inheritDoc}
*
* @implNote This implementation assumes that the ConcurrentMap cannot
* contain null values and get() returning null unambiguously means the key
* is absent. Implementations which support null values must override this
* default implementation.
*/
@Override
default
V
getOrDefault
(
Object
key
,
V
defaultValue
)
{
V
v
;
return
((
v
=
get
(
key
))
!=
null
)
?
v
:
defaultValue
;
}
/**
* If the specified key is not already associated
* with a value, associate it with the given value.
...
...
@@ -91,7 +106,7 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
* Removes the entry for a key only if currently mapped to a given value.
* This is equivalent to
* <pre> {@code
* if (map.containsKey(key) &&
map.get(key).equals(
value)) {
* if (map.containsKey(key) &&
Objects.equals(map.get(key),
value)) {
* map.remove(key);
* return true;
* } else
...
...
@@ -101,8 +116,8 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
*
* @param key key with which the specified value is associated
* @param value value expected to be associated with the specified key
* @return
<tt>true</tt>
if the value was removed
* @throws UnsupportedOperationException if the
<tt>remove</tt>
operation
* @return
{@code true}
if the value was removed
* @throws UnsupportedOperationException if the
{@code remove}
operation
* is not supported by this map
* @throws ClassCastException if the key or value is of an inappropriate
* type for this map
...
...
@@ -117,7 +132,7 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
* Replaces the entry for a key only if currently mapped to a given value.
* This is equivalent to
* <pre> {@code
* if (map.containsKey(key) &&
map.get(key).equals(
oldValue)) {
* if (map.containsKey(key) &&
Objects.equals(map.get(key),
oldValue)) {
* map.put(key, newValue);
* return true;
* } else
...
...
@@ -128,8 +143,8 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
* @param key key with which the specified value is associated
* @param oldValue value expected to be associated with the specified key
* @param newValue value to be associated with the specified key
* @return
<tt>true</tt>
if the value was replaced
* @throws UnsupportedOperationException if the
<tt>put</tt>
operation
* @return
{@code true}
if the value was replaced
* @throws UnsupportedOperationException if the
{@code put}
operation
* is not supported by this map
* @throws ClassCastException if the class of a specified key or value
* prevents it from being stored in this map
...
...
@@ -154,11 +169,11 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
* @param key key with which the specified value is associated
* @param value value to be associated with the specified key
* @return the previous value associated with the specified key, or
*
<tt>null</tt>
if there was no mapping for the key.
* (A
<tt>null</tt>
return can also indicate that the map
* previously associated
<tt>null</tt>
with the key,
*
{@code null}
if there was no mapping for the key.
* (A
{@code null}
return can also indicate that the map
* previously associated
{@code null}
with the key,
* if the implementation supports null values.)
* @throws UnsupportedOperationException if the
<tt>put</tt>
operation
* @throws UnsupportedOperationException if the
{@code put}
operation
* is not supported by this map
* @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map
...
...
test/java/util/Map/Defaults.java
0 → 100644
浏览文件 @
ad59a26e
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录