Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
df091906
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看板
提交
df091906
编写于
3月 08, 2013
作者:
M
mduigou
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8001667: Comparator combinators and extension methods
Reviewed-by: mduigou, briangoetz Contributed-by: henry.jen@oracle.com
上级
c702db81
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
763 addition
and
3 deletion
+763
-3
make/java/java/FILES_java.gmk
make/java/java/FILES_java.gmk
+1
-0
src/share/classes/java/util/Collections.java
src/share/classes/java/util/Collections.java
+1
-1
src/share/classes/java/util/Comparator.java
src/share/classes/java/util/Comparator.java
+94
-0
src/share/classes/java/util/Comparators.java
src/share/classes/java/util/Comparators.java
+279
-0
test/java/util/Collections/ReverseOrder.java
test/java/util/Collections/ReverseOrder.java
+35
-2
test/java/util/ComparatorsTest.java
test/java/util/ComparatorsTest.java
+353
-0
未找到文件。
make/java/java/FILES_java.gmk
浏览文件 @
df091906
...
...
@@ -257,6 +257,7 @@ JAVA_JAVA_java = \
sun/util/calendar/ZoneInfoFile.java \
java/util/TooManyListenersException.java \
java/util/Comparator.java \
java/util/Comparators.java \
java/util/Collections.java \
java/util/Iterator.java \
java/util/ListIterator.java \
...
...
src/share/classes/java/util/Collections.java
浏览文件 @
df091906
...
...
@@ -3759,7 +3759,7 @@ public class Collections {
return
c2
.
compareTo
(
c1
);
}
private
Object
readResolve
()
{
return
reverseOrder
();
}
private
Object
readResolve
()
{
return
Collections
.
reverseOrder
();
}
}
/**
...
...
src/share/classes/java/util/Comparator.java
浏览文件 @
df091906
...
...
@@ -25,6 +25,11 @@
package
java.util
;
import
java.util.function.Function
;
import
java.util.function.ToIntFunction
;
import
java.util.function.ToLongFunction
;
import
java.util.function.ToDoubleFunction
;
/**
* A comparison function, which imposes a <i>total ordering</i> on some
* collection of objects. Comparators can be passed to a sort method (such
...
...
@@ -165,4 +170,93 @@ public interface Comparator<T> {
* @see Object#hashCode()
*/
boolean
equals
(
Object
obj
);
/**
* Returns a comparator that imposes the reverse ordering of this
* comparator.
*
* @return A comparator that imposes the reverse ordering of this
* comparator.
* @since 1.8
*/
default
Comparator
<
T
>
reverseOrder
()
{
return
Collections
.
reverseOrder
(
this
);
}
/**
* Constructs a lexicographic order comparator with another comparator.
* For example, a {@code Comparator<Person> byLastName} can be composed
* with another {@code Comparator<Person> byFirstName}, then {@code
* byLastName.thenComparing(byFirstName)} creates a {@code
* Comparator<Person>} which sorts by last name, and for equal last names
* sorts by first name.
*
* @param other the other comparator used when equals on this.
* @throws NullPointerException if the argument is null.
* @since 1.8
*/
default
Comparator
<
T
>
thenComparing
(
Comparator
<?
super
T
>
other
)
{
return
Comparators
.
compose
(
this
,
other
);
}
/**
* Constructs a lexicographic order comparator with a function that
* extracts a {@code Comparable} key. This default implementation calls
* {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
*
* @param <U> the {@link Comparable} type for comparison
* @param keyExtractor the function used to extract the {@link Comparable} sort key
* @throws NullPointerException if the argument is null.
* @see Comparators#comparing(Function)
* @see #thenComparing(Comparator)
* @since 1.8
*/
default
<
U
extends
Comparable
<?
super
U
>>
Comparator
<
T
>
thenComparing
(
Function
<?
super
T
,
?
extends
U
>
keyExtractor
)
{
return
thenComparing
(
Comparators
.
comparing
(
keyExtractor
));
}
/**
* Constructs a lexicographic order comparator with a function that
* extracts a {@code int} value. This default implementation calls {@code
* thenComparing(this, Comparators.comparing(keyExtractor))}.
*
* @param keyExtractor the function used to extract the integer value
* @throws NullPointerException if the argument is null.
* @see Comparators#comparing(ToIntFunction)
* @see #thenComparing(Comparator)
* @since 1.8
*/
default
Comparator
<
T
>
thenComparing
(
ToIntFunction
<?
super
T
>
keyExtractor
)
{
return
thenComparing
(
Comparators
.
comparing
(
keyExtractor
));
}
/**
* Constructs a lexicographic order comparator with a function that
* extracts a {@code long} value. This default implementation calls
* {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
*
* @param keyExtractor the function used to extract the long value
* @throws NullPointerException if the argument is null.
* @see Comparators#comparing(ToLongFunction)
* @see #thenComparing(Comparator)
* @since 1.8
*/
default
Comparator
<
T
>
thenComparing
(
ToLongFunction
<?
super
T
>
keyExtractor
)
{
return
thenComparing
(
Comparators
.
comparing
(
keyExtractor
));
}
/**
* Constructs a lexicographic order comparator with a function that
* extracts a {@code double} value. This default implementation calls
* {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
*
* @param keyExtractor the function used to extract the double value
* @throws NullPointerException if the argument is null.
* @see Comparators#comparing(ToDoubleFunction)
* @see #thenComparing(Comparator)
* @since 1.8
*/
default
Comparator
<
T
>
thenComparing
(
ToDoubleFunction
<?
super
T
>
keyExtractor
)
{
return
thenComparing
(
Comparators
.
comparing
(
keyExtractor
));
}
}
src/share/classes/java/util/Comparators.java
0 → 100644
浏览文件 @
df091906
/*
* Copyright (c) 2012, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
java.util
;
import
java.io.Serializable
;
import
java.util.function.BinaryOperator
;
import
java.util.function.Function
;
import
java.util.function.ToDoubleFunction
;
import
java.util.function.ToIntFunction
;
import
java.util.function.ToLongFunction
;
/**
* This class consists of {@code static} utility methods for comparators. Mostly
* factory method that returns a {@link Comparator}.
*
* <p> Unless otherwise noted, passing a {@code null} argument to a method in
* this class will cause a {@link NullPointerException} to be thrown.
*
* @see Comparator
* @since 1.8
*/
public
class
Comparators
{
private
Comparators
()
{
throw
new
AssertionError
(
"no instances"
);
}
/**
* Compares {@link Comparable} objects in natural order.
*
* @see Comparable
*/
private
enum
NaturalOrderComparator
implements
Comparator
<
Comparable
<
Object
>>
{
INSTANCE
;
@Override
public
int
compare
(
Comparable
<
Object
>
c1
,
Comparable
<
Object
>
c2
)
{
return
c1
.
compareTo
(
c2
);
}
}
/**
* Returns a comparator that imposes the reverse of the <em>natural
* ordering</em>.
*
* <p>The returned comparator is serializable.
*
* @param <T> {@link Comparable} type
*
* @return A comparator that imposes the reverse of the <i>natural
* ordering</i> on a collection of objects that implement
* the {@link Comparable} interface.
* @see Comparable
*/
public
static
<
T
extends
Comparable
<?
super
T
>>
Comparator
<
T
>
reverseOrder
()
{
return
Collections
.
reverseOrder
();
}
/**
* Returns a comparator that imposes the reverse ordering of the specified
* {@link Comparator}.
*
* <p>The returned comparator is serializable (assuming the specified
* comparator is also serializable).
*
* @param <T> the element type to be compared
* @param cmp a comparator whose ordering is to be reversed by the returned
* comparator
* @return A comparator that imposes the reverse ordering of the
* specified comparator.
*/
public
static
<
T
>
Comparator
<
T
>
reverseOrder
(
Comparator
<
T
>
cmp
)
{
Objects
.
requireNonNull
(
cmp
);
return
Collections
.
reverseOrder
(
cmp
);
}
/**
* Gets a comparator compares {@link Comparable} type in natural order.
*
* @param <T> {@link Comparable} type
*/
public
static
<
T
extends
Comparable
<?
super
T
>>
Comparator
<
T
>
naturalOrder
()
{
return
(
Comparator
<
T
>)
NaturalOrderComparator
.
INSTANCE
;
}
/**
* Gets a comparator compares {@link Map.Entry} in natural order on key.
*
* @param <K> {@link Comparable} key type
* @param <V> value type
*/
public
static
<
K
extends
Comparable
<?
super
K
>,
V
>
Comparator
<
Map
.
Entry
<
K
,
V
>>
naturalOrderKeys
()
{
return
(
Comparator
<
Map
.
Entry
<
K
,
V
>>
&
Serializable
)
(
c1
,
c2
)
->
c1
.
getKey
().
compareTo
(
c2
.
getKey
());
}
/**
* Gets a comparator compares {@link Map.Entry} in natural order on value.
*
* @param <K> key type
* @param <V> {@link Comparable} value type
*/
public
static
<
K
,
V
extends
Comparable
<?
super
V
>>
Comparator
<
Map
.
Entry
<
K
,
V
>>
naturalOrderValues
()
{
return
(
Comparator
<
Map
.
Entry
<
K
,
V
>>
&
Serializable
)
(
c1
,
c2
)
->
c1
.
getValue
().
compareTo
(
c2
.
getValue
());
}
/**
* Gets a comparator compares {@link Map.Entry} by key using the given
* {@link Comparator}.
*
* <p>The returned comparator is serializable assuming the specified
* comparators are also serializable.
*
* @param <K> key type
* @param <V> value type
* @param cmp the key {@link Comparator}
*/
public
static
<
K
,
V
>
Comparator
<
Map
.
Entry
<
K
,
V
>>
byKey
(
Comparator
<?
super
K
>
cmp
)
{
Objects
.
requireNonNull
(
cmp
);
return
(
Comparator
<
Map
.
Entry
<
K
,
V
>>
&
Serializable
)
(
c1
,
c2
)
->
cmp
.
compare
(
c1
.
getKey
(),
c2
.
getKey
());
}
/**
* Gets a comparator compares {@link Map.Entry} by value using the given
* {@link Comparator}.
*
* @param <K> key type
* @param <V> value type
* @param cmp the value {@link Comparator}
*/
public
static
<
K
,
V
>
Comparator
<
Map
.
Entry
<
K
,
V
>>
byValue
(
Comparator
<?
super
V
>
cmp
)
{
Objects
.
requireNonNull
(
cmp
);
return
(
Comparator
<
Map
.
Entry
<
K
,
V
>>
&
Serializable
)
(
c1
,
c2
)
->
cmp
.
compare
(
c1
.
getValue
(),
c2
.
getValue
());
}
/**
* Accepts a function that extracts a {@link java.lang.Comparable
* Comparable} sort key from a type {@code T}, and returns a {@code
* Comparator<T>} that compares by that sort key. For example, if a class
* {@code Person} has a {@code String}-valued getter {@code getLastName},
* then {@code comparing(Person::getLastName)} would return a {@code
* Comparator<Person>} that compares {@code Person} objects by their last
* name.
*
* @param <T> the original element type
* @param <U> the {@link Comparable} type for comparison
* @param keyExtractor the function used to extract the {@link Comparable} sort key
*/
public
static
<
T
,
U
extends
Comparable
<?
super
U
>>
Comparator
<
T
>
comparing
(
Function
<?
super
T
,
?
extends
U
>
keyExtractor
)
{
Objects
.
requireNonNull
(
keyExtractor
);
return
(
Comparator
<
T
>
&
Serializable
)
(
c1
,
c2
)
->
keyExtractor
.
apply
(
c1
).
compareTo
(
keyExtractor
.
apply
(
c2
));
}
/**
* Accepts a function that extracts an {@code int} value from a type {@code
* T}, and returns a {@code Comparator<T>} that compares by that value.
*
* <p>The returned comparator is serializable assuming the specified
* function is also serializable.
*
* @see #comparing(Function)
* @param <T> the original element type
* @param keyExtractor the function used to extract the integer value
*/
public
static
<
T
>
Comparator
<
T
>
comparing
(
ToIntFunction
<?
super
T
>
keyExtractor
)
{
Objects
.
requireNonNull
(
keyExtractor
);
return
(
Comparator
<
T
>
&
Serializable
)
(
c1
,
c2
)
->
Integer
.
compare
(
keyExtractor
.
applyAsInt
(
c1
),
keyExtractor
.
applyAsInt
(
c2
));
}
/**
* Accepts a function that extracts a {@code long} value from a type {@code
* T}, and returns a {@code Comparator<T>} that compares by that value.
*
* <p>The returned comparator is serializable assuming the specified
* function is also serializable.
*
* @see #comparing(Function)
* @param <T> the original element type
* @param keyExtractor the function used to extract the long value
*/
public
static
<
T
>
Comparator
<
T
>
comparing
(
ToLongFunction
<?
super
T
>
keyExtractor
)
{
Objects
.
requireNonNull
(
keyExtractor
);
return
(
Comparator
<
T
>
&
Serializable
)
(
c1
,
c2
)
->
Long
.
compare
(
keyExtractor
.
applyAsLong
(
c1
),
keyExtractor
.
applyAsLong
(
c2
));
}
/**
* Accepts a function that extracts a {@code double} value from a type
* {@code T}, and returns a {@code Comparator<T>} that compares by that
* value.
*
* <p>The returned comparator is serializable assuming the specified
* function is also serializable.
*
* @see #comparing(Function)
* @param <T> the original element type
* @param keyExtractor the function used to extract the double value
*/
public
static
<
T
>
Comparator
<
T
>
comparing
(
ToDoubleFunction
<?
super
T
>
keyExtractor
)
{
Objects
.
requireNonNull
(
keyExtractor
);
return
(
Comparator
<
T
>
&
Serializable
)
(
c1
,
c2
)
->
Double
.
compare
(
keyExtractor
.
applyAsDouble
(
c1
),
keyExtractor
.
applyAsDouble
(
c2
));
}
/**
* Constructs a lexicographic order from two {@link Comparator}s. For
* example, if you have comparators {@code byLastName} and {@code
* byFirstName}, each of type {@code Comparator<Person>}, then {@code
* compose(byLastName, byFirstName)} creates a {@code Comparator<Person>}
* which sorts by last name, and for equal last names sorts by first name.
*
* <p>The returned comparator is serializable assuming the specified
* comparators are also serializable.
*
* @param <T> the element type to be compared
* @param first the first comparator
* @param second the secondary comparator used when equals on the first
*/
public
static
<
T
>
Comparator
<
T
>
compose
(
Comparator
<?
super
T
>
first
,
Comparator
<?
super
T
>
second
)
{
Objects
.
requireNonNull
(
first
);
Objects
.
requireNonNull
(
second
);
return
(
Comparator
<
T
>
&
Serializable
)
(
c1
,
c2
)
->
{
int
res
=
first
.
compare
(
c1
,
c2
);
return
(
res
!=
0
)
?
res
:
second
.
compare
(
c1
,
c2
);
};
}
/**
* Constructs a {@link BinaryOperator} which returns the lesser of two elements
* according to the specified {@code Comparator}
*
* @param comparator A {@code Comparator} for comparing the two values
* @param <T> the type of the elements to be compared
* @return a {@code BinaryOperator} which returns the lesser of its operands,
* according to the supplied {@code Comparator}
*/
public
static
<
T
>
BinaryOperator
<
T
>
lesserOf
(
Comparator
<?
super
T
>
comparator
)
{
return
(
a
,
b
)
->
comparator
.
compare
(
a
,
b
)
<=
0
?
a
:
b
;
}
/**
* Constructs a {@link BinaryOperator} which returns the greater of two elements
* according to the specified {@code Comparator}
*
* @param comparator A {@code Comparator} for comparing the two values
* @param <T> the type of the elements to be compared
* @return a {@code BinaryOperator} which returns the greater of its operands,
* according to the supplied {@code Comparator}
*/
public
static
<
T
>
BinaryOperator
<
T
>
greaterOf
(
Comparator
<?
super
T
>
comparator
)
{
return
(
a
,
b
)
->
comparator
.
compare
(
a
,
b
)
>=
0
?
a
:
b
;
}
}
test/java/util/Collections/ReverseOrder.java
浏览文件 @
df091906
...
...
@@ -23,23 +23,56 @@
/*
* @test
* @bug 4593209
* @bug 4593209
8001667
* @summary Reverse comparator was subtly broken
* @author Josh bloch
*/
import
java.util.*
;
import
java.io.*
;
public
class
ReverseOrder
{
static
byte
[]
serialBytes
(
Object
o
)
{
try
{
ByteArrayOutputStream
bos
=
new
ByteArrayOutputStream
();
ObjectOutputStream
oos
=
new
ObjectOutputStream
(
bos
);
oos
.
writeObject
(
o
);
oos
.
flush
();
oos
.
close
();
return
bos
.
toByteArray
();
}
catch
(
Throwable
t
)
{
throw
new
Error
(
t
);
}
}
@SuppressWarnings
(
"unchecked"
)
static
<
T
>
T
serialClone
(
T
o
)
{
try
{
ObjectInputStream
ois
=
new
ObjectInputStream
(
new
ByteArrayInputStream
(
serialBytes
(
o
)));
T
clone
=
(
T
)
ois
.
readObject
();
return
clone
;
}
catch
(
Throwable
t
)
{
throw
new
Error
(
t
);
}
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
Foo
[]
a
=
{
new
Foo
(
2
),
new
Foo
(
3
),
new
Foo
(
1
)
};
List
list
=
Arrays
.
asList
(
a
);
Collections
.
sort
(
list
,
Collections
.
reverseOrder
());
Comparator
cmp
=
Collections
.
reverseOrder
();
Collections
.
sort
(
list
,
cmp
);
Foo
[]
golden
=
{
new
Foo
(
3
),
new
Foo
(
2
),
new
Foo
(
1
)
};
List
goldenList
=
Arrays
.
asList
(
golden
);
if
(!
list
.
equals
(
goldenList
))
throw
new
Exception
(
list
.
toString
());
Comparator
clone
=
serialClone
(
cmp
);
List
list2
=
Arrays
.
asList
(
a
);
Collections
.
sort
(
list2
,
clone
);
if
(!
list2
.
equals
(
goldenList
))
throw
new
Exception
(
list
.
toString
());
}
}
...
...
test/java/util/ComparatorsTest.java
0 → 100644
浏览文件 @
df091906
/*
* Copyright (c) 2012, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8001667
* @run testng ComparatorsTest
*/
import
java.util.Comparator
;
import
java.util.Comparators
;
import
java.util.AbstractMap
;
import
java.util.Map
;
import
org.testng.annotations.Test
;
import
java.util.function.Function
;
import
java.util.function.ToIntFunction
;
import
java.util.function.ToLongFunction
;
import
java.util.function.ToDoubleFunction
;
import
static
org
.
testng
.
Assert
.
assertEquals
;
import
static
org
.
testng
.
Assert
.
assertTrue
;
import
static
org
.
testng
.
Assert
.
assertSame
;
/**
* Unit tests for helper methods in Comparators
*/
@Test
(
groups
=
"unit"
)
public
class
ComparatorsTest
{
private
static
class
Thing
{
public
final
int
intField
;
public
final
long
longField
;
public
final
double
doubleField
;
public
final
String
stringField
;
private
Thing
(
int
intField
,
long
longField
,
double
doubleField
,
String
stringField
)
{
this
.
intField
=
intField
;
this
.
longField
=
longField
;
this
.
doubleField
=
doubleField
;
this
.
stringField
=
stringField
;
}
public
int
getIntField
()
{
return
intField
;
}
public
long
getLongField
()
{
return
longField
;
}
public
double
getDoubleField
()
{
return
doubleField
;
}
public
String
getStringField
()
{
return
stringField
;
}
}
private
final
int
[]
intValues
=
{
-
2
,
-
2
,
-
1
,
-
1
,
0
,
0
,
1
,
1
,
2
,
2
};
private
final
long
[]
longValues
=
{
-
2
,
-
2
,
-
1
,
-
1
,
0
,
0
,
1
,
1
,
2
,
2
};
private
final
double
[]
doubleValues
=
{
-
2
,
-
2
,
-
1
,
-
1
,
0
,
0
,
1
,
1
,
2
,
2
};
private
final
String
[]
stringValues
=
{
"a"
,
"a"
,
"b"
,
"b"
,
"c"
,
"c"
,
"d"
,
"d"
,
"e"
,
"e"
};
private
final
int
[]
comparisons
=
{
0
,
-
1
,
0
,
-
1
,
0
,
-
1
,
0
,
-
1
,
0
};
private
<
T
>
void
assertComparisons
(
T
[]
things
,
Comparator
<
T
>
comp
,
int
[]
comparisons
)
{
for
(
int
i
=
0
;
i
<
comparisons
.
length
;
i
++)
{
assertEquals
(
comparisons
.
length
+
1
,
things
.
length
);
assertEquals
(
comparisons
[
i
],
comp
.
compare
(
things
[
i
],
things
[
i
+
1
]));
assertEquals
(-
comparisons
[
i
],
comp
.
compare
(
things
[
i
+
1
],
things
[
i
]));
}
}
public
void
testIntComparator
()
{
Thing
[]
things
=
new
Thing
[
intValues
.
length
];
for
(
int
i
=
0
;
i
<
intValues
.
length
;
i
++)
things
[
i
]
=
new
Thing
(
intValues
[
i
],
0L
,
0.0
,
null
);
Comparator
<
Thing
>
comp
=
Comparators
.
comparing
(
new
ToIntFunction
<
ComparatorsTest
.
Thing
>()
{
@Override
public
int
applyAsInt
(
Thing
thing
)
{
return
thing
.
getIntField
();
}
});
assertComparisons
(
things
,
comp
,
comparisons
);
}
public
void
testLongComparator
()
{
Thing
[]
things
=
new
Thing
[
longValues
.
length
];
for
(
int
i
=
0
;
i
<
longValues
.
length
;
i
++)
things
[
i
]
=
new
Thing
(
0
,
longValues
[
i
],
0.0
,
null
);
Comparator
<
Thing
>
comp
=
Comparators
.
comparing
(
new
ToLongFunction
<
ComparatorsTest
.
Thing
>()
{
@Override
public
long
applyAsLong
(
Thing
thing
)
{
return
thing
.
getLongField
();
}
});
assertComparisons
(
things
,
comp
,
comparisons
);
}
public
void
testDoubleComparator
()
{
Thing
[]
things
=
new
Thing
[
doubleValues
.
length
];
for
(
int
i
=
0
;
i
<
doubleValues
.
length
;
i
++)
things
[
i
]
=
new
Thing
(
0
,
0L
,
doubleValues
[
i
],
null
);
Comparator
<
Thing
>
comp
=
Comparators
.
comparing
(
new
ToDoubleFunction
<
ComparatorsTest
.
Thing
>()
{
@Override
public
double
applyAsDouble
(
Thing
thing
)
{
return
thing
.
getDoubleField
();
}
});
assertComparisons
(
things
,
comp
,
comparisons
);
}
public
void
testComparing
()
{
Thing
[]
things
=
new
Thing
[
doubleValues
.
length
];
for
(
int
i
=
0
;
i
<
doubleValues
.
length
;
i
++)
things
[
i
]
=
new
Thing
(
0
,
0L
,
0.0
,
stringValues
[
i
]);
Comparator
<
Thing
>
comp
=
Comparators
.
comparing
(
new
Function
<
Thing
,
String
>()
{
@Override
public
String
apply
(
Thing
thing
)
{
return
thing
.
getStringField
();
}
});
assertComparisons
(
things
,
comp
,
comparisons
);
}
public
void
testNaturalOrderComparator
()
{
Comparator
<
String
>
comp
=
Comparators
.
naturalOrder
();
assertComparisons
(
stringValues
,
comp
,
comparisons
);
}
public
void
testReverseComparator
()
{
Comparator
<
String
>
cmpr
=
Comparators
.
reverseOrder
();
Comparator
<
String
>
cmp
=
cmpr
.
reverseOrder
();
assertEquals
(
cmp
.
reverseOrder
(),
cmpr
);
assertEquals
(
0
,
cmp
.
compare
(
"a"
,
"a"
));
assertEquals
(
0
,
cmpr
.
compare
(
"a"
,
"a"
));
assertTrue
(
cmp
.
compare
(
"a"
,
"b"
)
<
0
);
assertTrue
(
cmpr
.
compare
(
"a"
,
"b"
)
>
0
);
assertTrue
(
cmp
.
compare
(
"b"
,
"a"
)
>
0
);
assertTrue
(
cmpr
.
compare
(
"b"
,
"a"
)
<
0
);
}
public
void
testReverseComparator2
()
{
Comparator
<
String
>
cmp
=
(
s1
,
s2
)
->
s1
.
length
()
-
s2
.
length
();
Comparator
<
String
>
cmpr
=
cmp
.
reverseOrder
();
assertEquals
(
cmpr
.
reverseOrder
(),
cmp
);
assertEquals
(
0
,
cmp
.
compare
(
"abc"
,
"def"
));
assertEquals
(
0
,
cmpr
.
compare
(
"abc"
,
"def"
));
assertTrue
(
cmp
.
compare
(
"abcd"
,
"def"
)
>
0
);
assertTrue
(
cmpr
.
compare
(
"abcd"
,
"def"
)
<
0
);
assertTrue
(
cmp
.
compare
(
"abc"
,
"defg"
)
<
0
);
assertTrue
(
cmpr
.
compare
(
"abc"
,
"defg"
)
>
0
);
}
@Test
(
expectedExceptions
=
NullPointerException
.
class
)
public
void
testReverseComparatorNPE
()
{
Comparator
<
String
>
cmp
=
Comparators
.
reverseOrder
(
null
);
}
public
void
testComposeComparator
()
{
// Longer string in front
Comparator
<
String
>
first
=
(
s1
,
s2
)
->
s2
.
length
()
-
s1
.
length
();
Comparator
<
String
>
second
=
Comparators
.
naturalOrder
();
Comparator
<
String
>
composed
=
Comparators
.
compose
(
first
,
second
);
assertTrue
(
composed
.
compare
(
"abcdefg"
,
"abcdef"
)
<
0
);
assertTrue
(
composed
.
compare
(
"abcdef"
,
"abcdefg"
)
>
0
);
assertTrue
(
composed
.
compare
(
"abcdef"
,
"abcdef"
)
==
0
);
assertTrue
(
composed
.
compare
(
"abcdef"
,
"ghijkl"
)
<
0
);
assertTrue
(
composed
.
compare
(
"ghijkl"
,
"abcdefg"
)
>
0
);
}
private
<
K
,
V
>
void
assertPairComparison
(
K
k1
,
V
v1
,
K
k2
,
V
v2
,
Comparator
<
Map
.
Entry
<
K
,
V
>>
ck
,
Comparator
<
Map
.
Entry
<
K
,
V
>>
cv
)
{
final
Map
.
Entry
<
K
,
V
>
p11
=
new
AbstractMap
.
SimpleImmutableEntry
<>(
k1
,
v1
);
final
Map
.
Entry
<
K
,
V
>
p12
=
new
AbstractMap
.
SimpleImmutableEntry
<>(
k1
,
v2
);
final
Map
.
Entry
<
K
,
V
>
p21
=
new
AbstractMap
.
SimpleImmutableEntry
<>(
k2
,
v1
);
final
Map
.
Entry
<
K
,
V
>
p22
=
new
AbstractMap
.
SimpleImmutableEntry
<>(
k2
,
v2
);
assertTrue
(
ck
.
compare
(
p11
,
p11
)
==
0
);
assertTrue
(
ck
.
compare
(
p12
,
p11
)
==
0
);
assertTrue
(
ck
.
compare
(
p11
,
p12
)
==
0
);
assertTrue
(
ck
.
compare
(
p12
,
p22
)
<
0
);
assertTrue
(
ck
.
compare
(
p12
,
p21
)
<
0
);
assertTrue
(
ck
.
compare
(
p21
,
p11
)
>
0
);
assertTrue
(
ck
.
compare
(
p21
,
p12
)
>
0
);
assertTrue
(
cv
.
compare
(
p11
,
p11
)
==
0
);
assertTrue
(
cv
.
compare
(
p12
,
p11
)
>
0
);
assertTrue
(
cv
.
compare
(
p11
,
p12
)
<
0
);
assertTrue
(
cv
.
compare
(
p12
,
p22
)
==
0
);
assertTrue
(
cv
.
compare
(
p12
,
p21
)
>
0
);
assertTrue
(
cv
.
compare
(
p21
,
p11
)
==
0
);
assertTrue
(
cv
.
compare
(
p21
,
p12
)
<
0
);
Comparator
<
Map
.
Entry
<
K
,
V
>>
cmp
=
Comparators
.
compose
(
ck
,
cv
);
assertTrue
(
cmp
.
compare
(
p11
,
p11
)
==
0
);
assertTrue
(
cmp
.
compare
(
p12
,
p11
)
>
0
);
assertTrue
(
cmp
.
compare
(
p11
,
p12
)
<
0
);
assertTrue
(
cmp
.
compare
(
p12
,
p22
)
<
0
);
assertTrue
(
cmp
.
compare
(
p12
,
p21
)
<
0
);
assertTrue
(
cmp
.
compare
(
p21
,
p11
)
>
0
);
assertTrue
(
cmp
.
compare
(
p21
,
p12
)
>
0
);
cmp
=
Comparators
.
compose
(
cv
,
ck
);
assertTrue
(
cmp
.
compare
(
p11
,
p11
)
==
0
);
assertTrue
(
cmp
.
compare
(
p12
,
p11
)
>
0
);
assertTrue
(
cmp
.
compare
(
p11
,
p12
)
<
0
);
assertTrue
(
cmp
.
compare
(
p12
,
p22
)
<
0
);
assertTrue
(
cmp
.
compare
(
p12
,
p21
)
>
0
);
assertTrue
(
cmp
.
compare
(
p21
,
p11
)
>
0
);
assertTrue
(
cmp
.
compare
(
p21
,
p12
)
<
0
);
}
public
void
testKVComparatorable
()
{
assertPairComparison
(
1
,
"ABC"
,
2
,
"XYZ"
,
Comparators
.<
Integer
,
String
>
naturalOrderKeys
(),
Comparators
.<
Integer
,
String
>
naturalOrderValues
());
}
private
static
class
People
{
final
String
firstName
;
final
String
lastName
;
final
int
age
;
People
(
String
first
,
String
last
,
int
age
)
{
firstName
=
first
;
lastName
=
last
;
this
.
age
=
age
;
}
String
getFirstName
()
{
return
firstName
;
}
String
getLastName
()
{
return
lastName
;
}
int
getAge
()
{
return
age
;
}
long
getAgeAsLong
()
{
return
(
long
)
age
;
};
double
getAgeAsDouble
()
{
return
(
double
)
age
;
};
}
private
final
People
people
[]
=
{
new
People
(
"John"
,
"Doe"
,
34
),
new
People
(
"Mary"
,
"Doe"
,
30
),
new
People
(
"Maria"
,
"Doe"
,
14
),
new
People
(
"Jonah"
,
"Doe"
,
10
),
new
People
(
"John"
,
"Cook"
,
54
),
new
People
(
"Mary"
,
"Cook"
,
50
),
};
public
void
testKVComparators
()
{
// Comparator<People> cmp = Comparators.naturalOrder(); // Should fail to compiler as People is not comparable
// We can use simple comparator, but those have been tested above.
// Thus choose to do compose for some level of interation.
Comparator
<
People
>
cmp1
=
Comparators
.
comparing
((
Function
<
People
,
String
>)
People:
:
getFirstName
);
Comparator
<
People
>
cmp2
=
Comparators
.
comparing
((
Function
<
People
,
String
>)
People:
:
getLastName
);
Comparator
<
People
>
cmp
=
Comparators
.
compose
(
cmp1
,
cmp2
);
assertPairComparison
(
people
[
0
],
people
[
0
],
people
[
1
],
people
[
1
],
Comparators
.<
People
,
People
>
byKey
(
cmp
),
Comparators
.<
People
,
People
>
byValue
(
cmp
));
}
private
<
T
>
void
assertComparison
(
Comparator
<
T
>
cmp
,
T
less
,
T
greater
)
{
assertTrue
(
cmp
.
compare
(
less
,
greater
)
<
0
,
"less"
);
assertTrue
(
cmp
.
compare
(
less
,
less
)
==
0
,
"equal"
);
assertTrue
(
cmp
.
compare
(
greater
,
less
)
>
0
,
"greater"
);
}
public
void
testComparatorDefaultMethods
()
{
Comparator
<
People
>
cmp
=
Comparators
.
comparing
((
Function
<
People
,
String
>)
People:
:
getFirstName
);
Comparator
<
People
>
cmp2
=
Comparators
.
comparing
((
Function
<
People
,
String
>)
People:
:
getLastName
);
// reverseOrder
assertComparison
(
cmp
.
reverseOrder
(),
people
[
1
],
people
[
0
]);
// thenComparing(Comparator)
assertComparison
(
cmp
.
thenComparing
(
cmp2
),
people
[
0
],
people
[
1
]);
assertComparison
(
cmp
.
thenComparing
(
cmp2
),
people
[
4
],
people
[
0
]);
// thenComparing(Function)
assertComparison
(
cmp
.
thenComparing
(
People:
:
getLastName
),
people
[
0
],
people
[
1
]);
assertComparison
(
cmp
.
thenComparing
(
People:
:
getLastName
),
people
[
4
],
people
[
0
]);
// thenComparing(ToIntFunction)
assertComparison
(
cmp
.
thenComparing
(
People:
:
getAge
),
people
[
0
],
people
[
1
]);
assertComparison
(
cmp
.
thenComparing
(
People:
:
getAge
),
people
[
1
],
people
[
5
]);
// thenComparing(ToLongFunction)
assertComparison
(
cmp
.
thenComparing
(
People:
:
getAgeAsLong
),
people
[
0
],
people
[
1
]);
assertComparison
(
cmp
.
thenComparing
(
People:
:
getAgeAsLong
),
people
[
1
],
people
[
5
]);
// thenComparing(ToDoubleFunction)
assertComparison
(
cmp
.
thenComparing
(
People:
:
getAgeAsDouble
),
people
[
0
],
people
[
1
]);
assertComparison
(
cmp
.
thenComparing
(
People:
:
getAgeAsDouble
),
people
[
1
],
people
[
5
]);
}
public
void
testGreaterOf
()
{
// lesser
assertSame
(
Comparators
.
greaterOf
(
Comparators
.
comparing
(
(
Function
<
People
,
String
>)
People:
:
getFirstName
))
.
apply
(
people
[
0
],
people
[
1
]),
people
[
1
]);
// euqal
assertSame
(
Comparators
.
greaterOf
(
Comparators
.
comparing
(
(
Function
<
People
,
String
>)
People:
:
getLastName
))
.
apply
(
people
[
0
],
people
[
1
]),
people
[
0
]);
// greater
assertSame
(
Comparators
.
greaterOf
(
Comparators
.
comparing
(
(
ToIntFunction
<
People
>)
People:
:
getAge
))
.
apply
(
people
[
0
],
people
[
1
]),
people
[
0
]);
}
public
void
testLesserOf
()
{
// lesser
assertSame
(
Comparators
.
lesserOf
(
Comparators
.
comparing
(
(
Function
<
People
,
String
>)
People:
:
getFirstName
))
.
apply
(
people
[
0
],
people
[
1
]),
people
[
0
]);
// euqal
assertSame
(
Comparators
.
lesserOf
(
Comparators
.
comparing
(
(
Function
<
People
,
String
>)
People:
:
getLastName
))
.
apply
(
people
[
0
],
people
[
1
]),
people
[
0
]);
// greater
assertSame
(
Comparators
.
lesserOf
(
Comparators
.
comparing
(
(
ToIntFunction
<
People
>)
People:
:
getAge
))
.
apply
(
people
[
0
],
people
[
1
]),
people
[
1
]);
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录