提交 83c573d4 编写于 作者: H henryjen

8009736: Comparator API cleanup

Reviewed-by: psandoz, briangoetz, mduigou, plevart
上级 071acd64
......@@ -4304,6 +4304,11 @@ public class Collections {
}
private Object readResolve() { return Collections.reverseOrder(); }
@Override
public Comparator<Comparable<Object>> reversed() {
return Comparator.naturalOrder();
}
}
/**
......@@ -4367,6 +4372,11 @@ public class Collections {
public int hashCode() {
return cmp.hashCode() ^ Integer.MIN_VALUE;
}
@Override
public Comparator<T> reversed() {
return cmp;
}
}
/**
......
......@@ -25,10 +25,12 @@
package java.util;
import java.io.Serializable;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.function.ToDoubleFunction;
import java.util.Comparators;
/**
* A comparison function, which imposes a <i>total ordering</i> on some
......@@ -175,88 +177,357 @@ public interface Comparator<T> {
* Returns a comparator that imposes the reverse ordering of this
* comparator.
*
* @return A comparator that imposes the reverse ordering of this
* @return a comparator that imposes the reverse ordering of this
* comparator.
* @since 1.8
*/
default Comparator<T> reverseOrder() {
default Comparator<T> reversed() {
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.
* Returns a lexicographic-order comparator with another comparator.
* If this {@code Comparator} considers two elements equal, i.e.
* {@code compare(a, b) == 0}, {@code other} is used to determine the order.
*
* <p>The returned comparator is serializable if the specified comparator
* is also serializable.
*
* @apiNote
* For example, to sort a collection of {@code String} based on the length
* and then case-insensitive natural ordering, the comparator can be
* composed using following code,
*
* <pre>{@code
* Comparator<String> cmp = Comparator.comparing(String::length)
* .thenComparing(String.CASE_INSENSITIVE_ORDER);
* }</pre>
*
* @param other the other comparator to be used when this comparator
* compares two objects that are equal.
* @return a lexicographic-order comparator composed of this and then the
* other comparator
* @throws NullPointerException if the argument is null.
* @since 1.8
*/
default Comparator<T> thenComparing(Comparator<? super T> other) {
return Comparators.compose(this, other);
Objects.requireNonNull(other);
return (Comparator<T> & Serializable) (c1, c2) -> {
int res = compare(c1, c2);
return (res != 0) ? res : other.compare(c1, c2);
};
}
/**
* Constructs a lexicographic order comparator with a function that
* extracts a {@code Comparable} key. This default implementation calls
* {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
* Returns a lexicographic-order comparator with a function that
* extracts a key to be compared with the given {@code Comparator}.
*
* @implSpec This default implementation behaves as if {@code
* thenComparing(comparing(keyExtractor, cmp))}.
*
* @param <U> the {@link Comparable} type for comparison
* @param keyExtractor the function used to extract the {@link Comparable} sort key
* @param <U> the type of the sort key
* @param keyExtractor the function used to extract the sort key
* @param keyComparator the {@code Comparator} used to compare the sort key
* @return a lexicographic-order comparator composed of this comparator
* and then comparing on the key extracted by the keyExtractor function
* @throws NullPointerException if the argument is null.
* @see Comparators#comparing(Function)
* @see #comparing(Function, Comparator)
* @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));
default <U extends Comparable<? super U>> Comparator<T> thenComparing(
Function<? super T, ? extends U> keyExtractor,
Comparator<? super U> keyComparator)
{
return thenComparing(comparing(keyExtractor, keyComparator));
}
/**
* Constructs a lexicographic order comparator with a function that
* extracts a {@code int} value. This default implementation calls {@code
* thenComparing(this, Comparators.comparing(keyExtractor))}.
* Returns a lexicographic-order comparator with a function that
* extracts a {@code Comparable} sort key.
*
* @implSpec This default implementation behaves as if {@code
* thenComparing(comparing(keyExtractor))}.
*
* @param keyExtractor the function used to extract the integer value
* @param <U> the type of the {@link Comparable} sort key
* @param keyExtractor the function used to extract the {@link
* Comparable} sort key
* @return a lexicographic-order comparator composed of this and then the
* {@link Comparable} sort key.
* @throws NullPointerException if the argument is null.
* @see Comparators#comparing(ToIntFunction)
* @see #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(comparing(keyExtractor));
}
/**
* Returns a lexicographic-order comparator with a function that
* extracts a {@code int} sort key.
*
* @implSpec This default implementation behaves as if {@code
* thenComparing(comparing(keyExtractor))}.
*
* @param keyExtractor the function used to extract the integer sort key
* @return a lexicographic-order comparator composed of this and then the
* {@code int} sort key
* @throws NullPointerException if the argument is null.
* @see #comparing(ToIntFunction)
* @see #thenComparing(Comparator)
* @since 1.8
*/
default Comparator<T> thenComparing(ToIntFunction<? super T> keyExtractor) {
return thenComparing(Comparators.comparing(keyExtractor));
return thenComparing(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))}.
* Returns a lexicographic-order comparator with a function that
* extracts a {@code long} sort key.
*
* @implSpec This default implementation behaves as if {@code
* thenComparing(comparing(keyExtractor))}.
*
* @param keyExtractor the function used to extract the long value
* @param keyExtractor the function used to extract the long sort key
* @return a lexicographic-order comparator composed of this and then the
* {@code long} sort key
* @throws NullPointerException if the argument is null.
* @see Comparators#comparing(ToLongFunction)
* @see #comparing(ToLongFunction)
* @see #thenComparing(Comparator)
* @since 1.8
*/
default Comparator<T> thenComparing(ToLongFunction<? super T> keyExtractor) {
return thenComparing(Comparators.comparing(keyExtractor));
return thenComparing(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))}.
* Returns a lexicographic-order comparator with a function that
* extracts a {@code double} sort key.
*
* @param keyExtractor the function used to extract the double value
* @implSpec This default implementation behaves as if {@code
* thenComparing(comparing(keyExtractor))}.
*
* @param keyExtractor the function used to extract the double sort key
* @return a lexicographic-order comparator composed of this and then the
* {@code double} sort key
* @throws NullPointerException if the argument is null.
* @see Comparators#comparing(ToDoubleFunction)
* @see #comparing(ToDoubleFunction)
* @see #thenComparing(Comparator)
* @since 1.8
*/
default Comparator<T> thenComparing(ToDoubleFunction<? super T> keyExtractor) {
return thenComparing(Comparators.comparing(keyExtractor));
return thenComparing(comparing(keyExtractor));
}
/**
* Returns a comparator that imposes the reverse of the <em>natural
* ordering</em>.
*
* <p>The returned comparator is serializable and throws {@link
* NullPointerException} when comparing {@code null}.
*
* @param <T> the {@link Comparable} type of element to be compared
* @return a comparator that imposes the reverse of the <i>natural
* ordering</i> on {@code Comparable} objects.
* @see Comparable
* @since 1.8
*/
public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
return Collections.reverseOrder();
}
/**
* Returns a comparator that compares {@link Comparable} objects in natural
* order.
*
* <p>The returned comparator is serializable and throws {@link
* NullPointerException} when comparing {@code null}.
*
* @param <T> the {@link Comparable} type of element to be compared
* @return a comparator that imposes the <i>natural ordering</i> on {@code
* Comparable} objects.
* @see Comparable
* @since 1.8
*/
public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
}
/**
* Returns a null-friendly comparator that considers {@code null} to be
* less than non-null. When both are {@code null}, they are considered
* equal. If both are non-null, the specified {@code Comparator} is used
* to determine the order. If the specified comparator is {@code null},
* then the returned comparator considers all non-null values to be equal.
*
* <p>The returned comparator is serializable if the specified comparator
* is serializable.
*
* @param <T> the type of the elements to be compared
* @param comparator a {@code Comparator} for comparing non-null values
* @return a comparator that considers {@code null} to be less than
* non-null, and compares non-null objects with the supplied
* {@code Comparator}.
* @since 1.8
*/
public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
return new Comparators.NullComparator(true, comparator);
}
/**
* Returns a null-friendly comparator that considers {@code null} to be
* greater than non-null. When both are {@code null}, they are considered
* equal. If both are non-null, the specified {@code Comparator} is used
* to determine the order. If the specified comparator is {@code null},
* then the returned comparator considers all non-null values to be equal.
*
* <p>The returned comparator is serializable if the specified comparator
* is serializable.
*
* @param <T> the type of the elements to be compared
* @param comparator a {@code Comparator} for comparing non-null values
* @return a comparator that considers {@code null} to be greater than
* non-null, and compares non-null objects with the supplied
* {@code Comparator}.
* @since 1.8
*/
public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {
return new Comparators.NullComparator(false, comparator);
}
/**
* Accepts a function that extracts a sort key from a type {@code T}, and
* returns a {@code Comparator<T>} that compares by that sort key using
* the specified {@link Comparator}.
*
* <p>The returned comparator is serializable if the specified function
* and comparator are both serializable.
*
* @apiNote
* For example, to obtain a {@code Comparator} that compares {@code
* Person} objects by their last name ignoring case differences,
*
* <pre>{@code
* Comparator<Person> cmp = Comparator.comparing(
* Person::getLastName,
* String.CASE_INSENSITIVE_ORDER);
* }</pre>
*
* @param <T> the type of element to be compared
* @param <U> the type of the sort key
* @param keyExtractor the function used to extract the sort key
* @param keyComparator the {@code Comparator} used to compare the sort key
* @return a comparator that compares by an extracted key using the
* specified {@code Comparator}
* @throws NullPointerException if either argument is null
* @since 1.8
*/
public static <T, U> Comparator<T> comparing(
Function<? super T, ? extends U> keyExtractor,
Comparator<? super U> keyComparator)
{
Objects.requireNonNull(keyExtractor);
Objects.requireNonNull(keyComparator);
return (Comparator<T> & Serializable)
(c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
keyExtractor.apply(c2));
}
/**
* 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.
*
* <p>The returned comparator is serializable if the specified function
* is also serializable.
*
* @apiNote
* For example, to obtain a {@code Comparator} that compares {@code
* Person} objects by their last name,
*
* <pre>{@code
* Comparator<Person> byLastName = Comparator.comparing(Person::getLastName);
* }</pre>
*
* @param <T> the type of element to be compared
* @param <U> the type of the {@code Comparable} sort key
* @param keyExtractor the function used to extract the {@link
* Comparable} sort key
* @return a comparator that compares by an extracted key
* @throws NullPointerException if the argument is null
* @since 1.8
*/
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} sort key from a type
* {@code T}, and returns a {@code Comparator<T>} that compares by that
* sort key.
*
* <p>The returned comparator is serializable if the specified function
* is also serializable.
*
* @param <T> the type of element to be compared
* @param keyExtractor the function used to extract the integer sort key
* @return a comparator that compares by an extracted key
* @see #comparing(Function)
* @throws NullPointerException if the argument is null
* @since 1.8
*/
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} sort key from a type
* {@code T}, and returns a {@code Comparator<T>} that compares by that
* sort key.
*
* <p>The returned comparator is serializable if the specified function is
* also serializable.
*
* @param <T> the type of element to be compared
* @param keyExtractor the function used to extract the long sort key
* @return a comparator that compares by an extracted key
* @see #comparing(Function)
* @throws NullPointerException if the argument is null
* @since 1.8
*/
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} sort key from a type
* {@code T}, and returns a {@code Comparator<T>} that compares by that
* sort key.
*
* <p>The returned comparator is serializable if the specified function
* is also serializable.
*
* @param <T> the type of element to be compared
* @param keyExtractor the function used to extract the double sort key
* @return a comparator that compares by an extracted key
* @see #comparing(Function)
* @throws NullPointerException if the argument is null
* @since 1.8
*/
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));
}
}
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013, 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
......@@ -32,16 +32,9 @@ 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
* Package private supporting class for {@link Comparator}.
*/
public class Comparators {
class Comparators {
private Comparators() {
throw new AssertionError("no instances");
}
......@@ -51,231 +44,55 @@ public class Comparators {
*
* @see Comparable
*/
private enum NaturalOrderComparator implements Comparator<Comparable<Object>> {
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));
@Override
public Comparator<Comparable<Object>> reversed() {
return Comparator.reverseOrder();
}
}
/**
* 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
* Null-friendly comparators
*/
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));
}
final static class NullComparator<T> implements Comparator<T>, Serializable {
private static final long serialVersionUID = -7569533591570686392L;
private final boolean nullFirst;
// if null, non-null Ts are considered equal
private final Comparator<T> real;
@SuppressWarnings("unchecked")
NullComparator(boolean nullFirst, Comparator<? super T> real) {
this.nullFirst = nullFirst;
this.real = (Comparator<T>) real;
}
/**
* 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);
};
}
@Override
public int compare(T a, T b) {
if (a == null) {
return (b == null) ? 0 : (nullFirst ? -1 : 1);
} else if (b == null) {
return nullFirst ? 1: -1;
} else {
return (real == null) ? 0 : real.compare(a, b);
}
}
/**
* 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) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
}
@Override
public Comparator<T> thenComparing(Comparator<? super T> other) {
Objects.requireNonNull(other);
return new NullComparator(nullFirst, real == null ? other : real.thenComparing(other));
}
/**
* 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) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
@Override
public Comparator<T> reversed() {
return new NullComparator(!nullFirst, real == null ? null : real.reversed());
}
}
}
......@@ -28,6 +28,7 @@ package java.util;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.io.Serializable;
/**
* An object that maps keys to values. A map cannot contain duplicate keys;
......@@ -446,6 +447,74 @@ public interface Map<K,V> {
* @see #equals(Object)
*/
int hashCode();
/**
* Returns a comparator that compares {@link Map.Entry} in natural order on key.
*
* <p>The returned comparator is serializable and throws {@link
* NullPointerException} when comparing an entry with a null key.
*
* @param <K> the {@link Comparable} type of then map keys
* @param <V> the type of the map values
* @return a comparator that compares {@link Map.Entry} in natural order on key.
* @see Comparable
*/
public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> c1.getKey().compareTo(c2.getKey());
}
/**
* Returns a comparator that compares {@link Map.Entry} in natural order on value.
*
* <p>The returned comparator is serializable and throws {@link
* NullPointerException} when comparing an entry with null values.
*
* @param <K> the type of the map keys
* @param <V> the {@link Comparable} type of the map values
* @return a comparator that compares {@link Map.Entry} in natural order on value.
* @see Comparable
*/
public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() {
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> c1.getValue().compareTo(c2.getValue());
}
/**
* Returns a comparator that compares {@link Map.Entry} by key using the given
* {@link Comparator}.
*
* <p>The returned comparator is serializable if the specified comparator
* is also serializable.
*
* @param <K> the type of the map keys
* @param <V> the type of the map values
* @param cmp the key {@link Comparator}
* @return a comparator that compares {@link Map.Entry} by the key.
*/
public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
Objects.requireNonNull(cmp);
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
}
/**
* Returns a comparator that compares {@link Map.Entry} by value using the given
* {@link Comparator}.
*
* <p>The returned comparator is serializable if the specified comparator
* is also serializable.
*
* @param <K> the type of the map keys
* @param <V> the type of the map values
* @param cmp the value {@link Comparator}
* @return a comparator that compares {@link Map.Entry} by the value.
*/
public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
Objects.requireNonNull(cmp);
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
}
}
// Comparison and hashing
......
......@@ -2938,13 +2938,13 @@ public class TreeMap<K,V>
public int characteristics() {
return (side == 0 ? Spliterator.SIZED : 0) |
Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED;
Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED;
}
@Override
public Comparator<? super Map.Entry<K, V>> getComparator() {
return tree.comparator != null ?
Comparators.byKey(tree.comparator) : null;
Map.Entry.comparingByKey(tree.comparator) : null;
}
}
}
......@@ -24,6 +24,9 @@
*/
package java.util.function;
import java.util.Objects;
import java.util.Comparator;
/**
* An operation upon two operands yielding a result. This is a specialization of
* {@code BiFunction} where the operands and the result are all of the same type.
......@@ -35,4 +38,31 @@ package java.util.function;
*/
@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
/**
* Returns 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
* @return a {@code BinaryOperator} which returns the lesser of its operands,
* according to the supplied {@code Comparator}
* @throws NullPointerException if the argument is null
*/
public static<T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
}
/**
* Returns 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
* @return a {@code BinaryOperator} which returns the greater of its operands,
* according to the supplied {@code Comparator}
* @throws NullPointerException if the argument is null
*/
public static<T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
}
}
......@@ -30,7 +30,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Comparators;
import java.util.DoubleSummaryStatistics;
import java.util.EnumSet;
import java.util.HashMap;
......@@ -78,7 +77,7 @@ import java.util.function.ToLongFunction;
*
* // Find highest-paid employee
* Employee highestPaid = employees.stream()
* .collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary)));
* .collect(Collectors.maxBy(Comparator.comparing(Employee::getSalary)));
*
* // Group employees by department
* Map<Department, List<Employee>> byDept
......@@ -89,7 +88,7 @@ import java.util.function.ToLongFunction;
* Map<Department, Employee> highestPaidByDept
* = employees.stream()
* .collect(Collectors.groupingBy(Employee::getDepartment,
* Collectors.maxBy(Comparators.comparing(Employee::getSalary))));
* Collectors.maxBy(Comparator.comparing(Employee::getSalary))));
*
* // Partition students into passing and failing
* Map<Boolean, List<Student>> passingFailing =
......@@ -404,7 +403,7 @@ public final class Collectors {
* @implSpec
* This produces a result equivalent to:
* <pre>{@code
* reducing(Comparators.lesserOf(comparator))
* reducing(BinaryOperator.minBy(comparator))
* }</pre>
*
* @param <T> the type of the input elements
......@@ -413,7 +412,7 @@ public final class Collectors {
*/
public static <T> Collector<T, T>
minBy(Comparator<? super T> comparator) {
return reducing(Comparators.lesserOf(comparator));
return reducing(BinaryOperator.minBy(comparator));
}
/**
......@@ -423,7 +422,7 @@ public final class Collectors {
* @implSpec
* This produces a result equivalent to:
* <pre>{@code
* reducing(Comparators.greaterOf(comparator))
* reducing(BinaryOperator.maxBy(comparator))
* }</pre>
*
* @param <T> the type of the input elements
......@@ -432,7 +431,7 @@ public final class Collectors {
*/
public static <T> Collector<T, T>
maxBy(Comparator<? super T> comparator) {
return reducing(Comparators.greaterOf(comparator));
return reducing(BinaryOperator.maxBy(comparator));
}
/**
......@@ -491,8 +490,8 @@ public final class Collectors {
* <p>For example, given a stream of {@code Person}, to calculate tallest
* person in each city:
* <pre>{@code
* Comparator<Person> byHeight = Comparators.comparing(Person::getHeight);
* BinaryOperator<Person> tallerOf = Comparators.greaterOf(byHeight);
* Comparator<Person> byHeight = Comparator.comparing(Person::getHeight);
* BinaryOperator<Person> tallerOf = BinaryOperator.greaterOf(byHeight);
* Map<City, Person> tallestByCity
* = people.stream().collect(groupingBy(Person::getCity, reducing(tallerOf)));
* }</pre>
......@@ -531,8 +530,8 @@ public final class Collectors {
* <p>For example, given a stream of {@code Person}, to calculate the longest
* last name of residents in each city:
* <pre>{@code
* Comparator<String> byLength = Comparators.comparing(String::length);
* BinaryOperator<String> longerOf = Comparators.greaterOf(byLength);
* Comparator<String> byLength = Comparator.comparing(String::length);
* BinaryOperator<String> longerOf = BinaryOperator.greaterOf(byLength);
* Map<City, String> longestLastNameByCity
* = people.stream().collect(groupingBy(Person::getCity,
* reducing(Person::getLastName, longerOf)));
......
......@@ -25,7 +25,6 @@
package java.util.stream;
import java.util.Comparator;
import java.util.Comparators;
import java.util.Iterator;
import java.util.Objects;
import java.util.Optional;
......@@ -512,12 +511,12 @@ abstract class ReferencePipeline<P_IN, P_OUT>
@Override
public final Optional<P_OUT> max(Comparator<? super P_OUT> comparator) {
return reduce(Comparators.greaterOf(comparator));
return reduce(BinaryOperator.maxBy(comparator));
}
@Override
public final Optional<P_OUT> min(Comparator<? super P_OUT> comparator) {
return reduce(Comparators.lesserOf(comparator));
return reduce(BinaryOperator.minBy(comparator));
}
......
......@@ -27,7 +27,6 @@ package java.util.stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Comparators;
import java.util.Objects;
import java.util.Spliterator;
import java.util.concurrent.ForkJoinTask;
......@@ -114,7 +113,7 @@ final class SortedOps {
StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SORTED);
this.isNaturalSort = true;
// Will throw CCE when we try to sort if T is not Comparable
this.comparator = (Comparator<? super T>) Comparators.naturalOrder();
this.comparator = (Comparator<? super T>) Comparator.naturalOrder();
}
/**
......
......@@ -43,7 +43,7 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.Comparators;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
......@@ -139,7 +139,7 @@ public class StreamTest {
public void testBasic() {
try (CloseableStream<Path> s = Files.list(testFolder)) {
Object[] actual = s.sorted(Comparators.naturalOrder()).toArray();
Object[] actual = s.sorted(Comparator.naturalOrder()).toArray();
assertEquals(actual, level1);
} catch (IOException ioe) {
fail("Unexpected IOException");
......@@ -155,7 +155,7 @@ public class StreamTest {
public void testWalk() {
try (CloseableStream<Path> s = Files.walk(testFolder)) {
Object[] actual = s.sorted(Comparators.naturalOrder()).toArray();
Object[] actual = s.sorted(Comparator.naturalOrder()).toArray();
assertEquals(actual, all);
} catch (IOException ioe) {
fail("Unexpected IOException");
......@@ -165,7 +165,7 @@ public class StreamTest {
public void testWalkOneLevel() {
try (CloseableStream<Path> s = Files.walk(testFolder, 1)) {
Object[] actual = s.filter(path -> ! path.equals(testFolder))
.sorted(Comparators.naturalOrder())
.sorted(Comparator.naturalOrder())
.toArray();
assertEquals(actual, level1);
} catch (IOException ioe) {
......@@ -177,7 +177,7 @@ public class StreamTest {
// If link is not supported, the directory structure won't have link.
// We still want to test the behavior with FOLLOW_LINKS option.
try (CloseableStream<Path> s = Files.walk(testFolder, FileVisitOption.FOLLOW_LINKS)) {
Object[] actual = s.sorted(Comparators.naturalOrder()).toArray();
Object[] actual = s.sorted(Comparator.naturalOrder()).toArray();
assertEquals(actual, all_folowLinks);
} catch (IOException ioe) {
fail("Unexpected IOException");
......@@ -637,13 +637,13 @@ public class StreamTest {
public void testClosedStream() throws IOException {
try (CloseableStream<Path> s = Files.list(testFolder)) {
s.close();
Object[] actual = s.sorted(Comparators.naturalOrder()).toArray();
Object[] actual = s.sorted(Comparator.naturalOrder()).toArray();
assertTrue(actual.length <= level1.length);
}
try (CloseableStream<Path> s = Files.walk(testFolder)) {
s.close();
Object[] actual = s.sorted(Comparators.naturalOrder()).toArray();
Object[] actual = s.sorted(Comparator.naturalOrder()).toArray();
fail("Operate on closed stream should throw IllegalStateException");
} catch (IllegalStateException ex) {
// expected
......@@ -652,7 +652,7 @@ public class StreamTest {
try (CloseableStream<Path> s = Files.find(testFolder, Integer.MAX_VALUE,
(p, attr) -> true)) {
s.close();
Object[] actual = s.sorted(Comparators.naturalOrder()).toArray();
Object[] actual = s.sorted(Comparator.naturalOrder()).toArray();
fail("Operate on closed stream should throw IllegalStateException");
} catch (IllegalStateException ex) {
// expected
......
......@@ -25,7 +25,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Comparators;
import java.util.List;
import java.util.LinkedList;
import java.util.Stack;
......@@ -337,23 +336,23 @@ public class ListDefaults {
CollectionSupplier.shuffle(list);
list.sort(null);
CollectionAsserts.assertSorted(list, Comparators.<Integer>naturalOrder());
CollectionAsserts.assertSorted(list, Comparator.<Integer>naturalOrder());
if (test.name.startsWith("reverse")) {
Collections.reverse(list);
}
CollectionAsserts.assertContents(list, original);
CollectionSupplier.shuffle(list);
list.sort(Comparators.<Integer>naturalOrder());
CollectionAsserts.assertSorted(list, Comparators.<Integer>naturalOrder());
list.sort(Comparator.<Integer>naturalOrder());
CollectionAsserts.assertSorted(list, Comparator.<Integer>naturalOrder());
if (test.name.startsWith("reverse")) {
Collections.reverse(list);
}
CollectionAsserts.assertContents(list, original);
CollectionSupplier.shuffle(list);
list.sort(Comparators.<Integer>reverseOrder());
CollectionAsserts.assertSorted(list, Comparators.<Integer>reverseOrder());
list.sort(Comparator.<Integer>reverseOrder());
CollectionAsserts.assertSorted(list, Comparator.<Integer>reverseOrder());
if (!test.name.startsWith("reverse")) {
Collections.reverse(list);
}
......@@ -390,8 +389,8 @@ public class ListDefaults {
final List<Integer> copy = new ArrayList<>(list);
final List<Integer> subList = list.subList(SUBLIST_FROM, SUBLIST_TO);
CollectionSupplier.shuffle(subList);
subList.sort(Comparators.<Integer>naturalOrder());
CollectionAsserts.assertSorted(subList, Comparators.<Integer>naturalOrder());
subList.sort(Comparator.<Integer>naturalOrder());
CollectionAsserts.assertSorted(subList, Comparator.<Integer>naturalOrder());
// verify that elements [0, from) remain unmodified
for (int i = 0; i < SUBLIST_FROM; i++) {
assertTrue(list.get(i) == copy.get(i),
......@@ -412,8 +411,8 @@ public class ListDefaults {
public void call(final List<Integer> list) {
final List<Integer> copy = new ArrayList<>(list);
CollectionSupplier.shuffle(list);
list.sort(Comparators.<Integer>naturalOrder());
CollectionAsserts.assertSorted(list, Comparators.<Integer>naturalOrder());
list.sort(Comparator.<Integer>naturalOrder());
CollectionAsserts.assertSorted(list, Comparator.<Integer>naturalOrder());
}
});
}
......
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 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
......@@ -21,19 +21,16 @@
* questions.
*/
/*
/**
* @test
* @bug 8001667 8010279
* @summary Comparator default method tests
* @run testng BasicTest
*/
import java.util.TreeMap;
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.BinaryOperator;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
......@@ -41,12 +38,8 @@ import java.util.function.ToDoubleFunction;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.fail;
/**
* Unit tests for helper methods in Comparators
*/
@Test(groups = "unit")
public class BasicTest {
private static class Thing {
......@@ -97,7 +90,7 @@ public class BasicTest {
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<BasicTest.Thing>() {
Comparator<Thing> comp = Comparator.comparing(new ToIntFunction<Thing>() {
@Override
public int applyAsInt(Thing thing) {
return thing.getIntField();
......@@ -111,7 +104,7 @@ public class BasicTest {
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<BasicTest.Thing>() {
Comparator<Thing> comp = Comparator.comparing(new ToLongFunction<Thing>() {
@Override
public long applyAsLong(Thing thing) {
return thing.getLongField();
......@@ -125,7 +118,7 @@ public class BasicTest {
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<BasicTest.Thing>() {
Comparator<Thing> comp = Comparator.comparing(new ToDoubleFunction<Thing>() {
@Override
public double applyAsDouble(Thing thing) {
return thing.getDoubleField();
......@@ -139,7 +132,7 @@ public class BasicTest {
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>() {
Comparator<Thing> comp = Comparator.comparing(new Function<Thing, String>() {
@Override
public String apply(Thing thing) {
return thing.getStringField();
......@@ -150,16 +143,16 @@ public class BasicTest {
}
public void testNaturalOrderComparator() {
Comparator<String> comp = Comparators.naturalOrder();
Comparator<String> comp = Comparator.naturalOrder();
assertComparisons(stringValues, comp, comparisons);
}
public void testReverseComparator() {
Comparator<String> cmpr = Comparators.reverseOrder();
Comparator<String> cmp = cmpr.reverseOrder();
Comparator<String> cmpr = Comparator.reverseOrder();
Comparator<String> cmp = cmpr.reversed();
assertEquals(cmp.reverseOrder(), cmpr);
assertEquals(cmp.reversed(), cmpr);
assertEquals(0, cmp.compare("a", "a"));
assertEquals(0, cmpr.compare("a", "a"));
assertTrue(cmp.compare("a", "b") < 0);
......@@ -170,9 +163,9 @@ public class BasicTest {
public void testReverseComparator2() {
Comparator<String> cmp = (s1, s2) -> s1.length() - s2.length();
Comparator<String> cmpr = cmp.reverseOrder();
Comparator<String> cmpr = cmp.reversed();
assertEquals(cmpr.reverseOrder(), cmp);
assertEquals(cmpr.reversed(), cmp);
assertEquals(0, cmp.compare("abc", "def"));
assertEquals(0, cmpr.compare("abc", "def"));
assertTrue(cmp.compare("abcd", "def") > 0);
......@@ -181,71 +174,11 @@ public class BasicTest {
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 <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, greater) == 0, "equal");
assertTrue(cmp.compare(greater, less) > 0, "greater");
}
private static class People {
......@@ -273,33 +206,15 @@ public class BasicTest {
new People("Jonah", "Doe", 10),
new People("John", "Cook", 54),
new People("Mary", "Cook", 50),
new People("Mary", null, 25),
new People("John", null, 27)
};
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);
Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName);
Comparator<People> cmp2 = Comparator.comparing((Function<People, String>) People::getLastName);
// reverseOrder
assertComparison(cmp.reverseOrder(), people[1], people[0]);
assertComparison(cmp.reversed(), people[1], people[0]);
// thenComparing(Comparator)
assertComparison(cmp.thenComparing(cmp2), people[0], people[1]);
assertComparison(cmp.thenComparing(cmp2), people[4], people[0]);
......@@ -317,96 +232,138 @@ public class BasicTest {
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 testNullsFirst() {
Comparator<String> strcmp = Comparator.nullsFirst(Comparator.naturalOrder());
Comparator<People> cmp = Comparator.<People, String>comparing(People::getLastName, strcmp)
.thenComparing(People::getFirstName, strcmp);
// Mary.null vs Mary.Cook - solve by last name
assertComparison(cmp, people[6], people[5]);
// John.null vs Mary.null - solve by first name
assertComparison(cmp, people[7], people[6]);
// More than one thenComparing
strcmp = Comparator.nullsFirst(Comparator.comparing((ToIntFunction<String>) String::length)
.thenComparing(String.CASE_INSENSITIVE_ORDER));
assertComparison(strcmp, null, "abc");
assertComparison(strcmp, "ab", "abc");
assertComparison(strcmp, "abc", "def");
assertEquals(0, strcmp.compare("abc", "ABC"));
// Ensure reverse still handle null properly
Comparator<String> strcmp2 = strcmp.reversed().thenComparing(Comparator.naturalOrder());
assertComparison(strcmp2, "abc", null);
assertComparison(strcmp2, "abc", "ab");
assertComparison(strcmp2, "def", "abc");
assertComparison(strcmp2, "ABC", "abc");
// Considering non-null values to be equal
Comparator<String> blind = Comparator.nullsFirst(null);
assertComparison(blind, null, "abc");
assertEquals(0, blind.compare("abc", "def"));
// reverse still consider non-null values to be equal
strcmp = blind.reversed();
assertComparison(strcmp, "abc", null);
assertEquals(0, strcmp.compare("abc", "def"));
// chain with another comparator to compare non-nulls
strcmp = blind.thenComparing(Comparator.naturalOrder());
assertComparison(strcmp, null, "abc");
assertComparison(strcmp, "abc", "def");
}
public void testNullsLast() {
Comparator<String> strcmp = Comparator.nullsLast(Comparator.naturalOrder());
Comparator<People> cmp = Comparator.<People, String>comparing(People::getLastName, strcmp)
.thenComparing(People::getFirstName, strcmp);
// Mary.null vs Mary.Cook - solve by last name
assertComparison(cmp, people[5], people[6]);
// John.null vs Mary.null - solve by first name
assertComparison(cmp, people[7], people[6]);
// More than one thenComparing
strcmp = Comparator.nullsLast(Comparator.comparing((ToIntFunction<String>) String::length)
.thenComparing(String.CASE_INSENSITIVE_ORDER));
assertComparison(strcmp, "abc", null);
assertComparison(strcmp, "ab", "abc");
assertComparison(strcmp, "abc", "def");
// Ensure reverse still handle null properly
Comparator<String> strcmp2 = strcmp.reversed().thenComparing(Comparator.naturalOrder());
assertComparison(strcmp2, null, "abc");
assertComparison(strcmp2, "abc", "ab");
assertComparison(strcmp2, "def", "abc");
assertComparison(strcmp2, "ABC", "abc");
// Considering non-null values to be equal
Comparator<String> blind = Comparator.nullsLast(null);
assertComparison(blind, "abc", null);
assertEquals(0, blind.compare("abc", "def"));
// reverse still consider non-null values to be equal
strcmp = blind.reversed();
assertComparison(strcmp, null, "abc");
assertEquals(0, strcmp.compare("abc", "def"));
// chain with another comparator to compare non-nulls
strcmp = blind.thenComparing(Comparator.naturalOrder());
assertComparison(strcmp, "abc", null);
assertComparison(strcmp, "abc", "def");
}
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]);
public void testComposeComparator() {
// Longer string in front
Comparator<String> first = (s1, s2) -> s2.length() - s1.length();
Comparator<String> second = Comparator.naturalOrder();
Comparator<String> composed = first.thenComparing(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);
}
public void testNulls() {
try {
Comparators.<String>naturalOrder().compare("abc", (String) null);
Comparator.<String>naturalOrder().compare("abc", (String) null);
fail("expected NPE with naturalOrder");
} catch (NullPointerException npe) {}
try {
Comparators.<String>naturalOrder().compare((String) null, "abc");
Comparator.<String>naturalOrder().compare((String) null, "abc");
fail("expected NPE with naturalOrder");
} catch (NullPointerException npe) {}
try {
Comparators.<String>reverseOrder().compare("abc", (String) null);
Comparator.<String>reverseOrder().compare("abc", (String) null);
fail("expected NPE with naturalOrder");
} catch (NullPointerException npe) {}
try {
Comparators.<String>reverseOrder().compare((String) null, "abc");
Comparator.<String>reverseOrder().compare((String) null, "abc");
fail("expected NPE with naturalOrder");
} catch (NullPointerException npe) {}
try {
Comparator<Map.Entry<String, String>> cmp = Comparators.byKey(null);
fail("byKey(null) should throw NPE");
Comparator<People> cmp = Comparator.comparing((Function<People, String>) null, Comparator.<String>naturalOrder());
fail("comparing(null, cmp) should throw NPE");
} catch (NullPointerException npe) {}
try {
Comparator<Map.Entry<String, String>> cmp = Comparators.byValue(null);
fail("byValue(null) should throw NPE");
Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName, null);
fail("comparing(f, null) should throw NPE");
} catch (NullPointerException npe) {}
try {
Comparator<People> cmp = Comparators.comparing((Function<People, String>) null);
Comparator<People> cmp = Comparator.comparing((Function<People, String>) null);
fail("comparing(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
Comparator<People> cmp = Comparators.comparing((ToIntFunction<People>) null);
Comparator<People> cmp = Comparator.comparing((ToIntFunction<People>) null);
fail("comparing(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
Comparator<People> cmp = Comparators.comparing((ToLongFunction<People>) null);
Comparator<People> cmp = Comparator.comparing((ToLongFunction<People>) null);
fail("comparing(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
Comparator<People> cmp = Comparators.comparing((ToDoubleFunction<People>) null);
Comparator<People> cmp = Comparator.comparing((ToDoubleFunction<People>) null);
fail("comparing(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
BinaryOperator<String> op = Comparators.lesserOf(null);
fail("lesserOf(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
BinaryOperator<String> op = Comparators.greaterOf(null);
fail("lesserOf(null) should throw NPE");
} catch (NullPointerException npe) {}
}
}
/*
* Copyright (c) 2013, 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
* @summary Comparator API narrowing type test
* @run testng TypeTest
*/
import java.util.function.Function;
import java.util.Map;
import java.util.TreeMap;
import java.util.Comparator;
import org.testng.annotations.Test;
@Test(groups = "unit")
public class TypeTest {
static class Person {
String name;
static Comparator<Person> C = (p1, p2) -> p1.name.compareTo(p2.name);
Person(String name) {
this.name = name;
}
String getName() { return name; }
}
static class Employee extends Person {
int id;
static Comparator<Employee> C = (e1, e2) -> e1.id - e2.id;
Employee(int id, String name) {
super(name);
this.id = id;
}
}
static class Manager extends Employee {
long reports;
static Comparator<Manager> C = (e1, e2) -> (int) (e1.reports - e2.reports);
Manager(String name, int id, long reports) {
super(id, name);
this.reports = reports;
}
}
static <T> void assertOrder(T o1, T o2, Comparator<? super T> cmp) {
if (cmp.compare(o1, o2) > 0) {
System.out.println("Fail!!");
}
if (cmp.compare(o1, o2) == 0) {
System.out.println("Equal!!");
}
}
public static void main(String[] args) {
Manager m1 = new Manager("Manager", 2, 2000);
Manager m2 = new Manager("Manager", 4, 1300);
// Comparator<Employee> tmp = Person.C;
// Comparator<Manager> cmp = Employee.C.thenComparing(Person.C);
Comparator<Employee> cmp = Employee.C.thenComparing(Person.C);
assertOrder(m1, m2, Employee.C.thenComparing(Person.C));
assertOrder(m1, m2, cmp);
assertOrder(m1, new Employee(1, "Z"), Person.C);
assertOrder(new Employee(1, "Z"), m2, Employee.C);
assertOrder(m1, m2, Comparator.comparing(Employee::getName, String.CASE_INSENSITIVE_ORDER));
Map<String, Integer> map = new TreeMap<>();
map.entrySet().stream().sorted(Map.Entry.comparingByKey(String.CASE_INSENSITIVE_ORDER));
}
}
/*
* 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 8009736 8010279
* @run testng EntryComparators
*/
import java.util.function.Function;
import java.util.Comparator;
import java.util.AbstractMap;
import java.util.Map;
import org.testng.annotations.Test;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
/**
* Unit tests for Map.Entry.comparing
*/
@Test(groups = "unit")
public class EntryComparators {
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 = ck.thenComparing(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 = cv.thenComparing(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 testKVComparables() {
assertPairComparison(1, "ABC", 2, "XYZ",
Map.Entry.<Integer, String>comparingByKey(),
Map.Entry.<Integer, String>comparingByValue());
}
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; }
}
private final People people[] = {
new People("John", "Doe", 34),
new People("Mary", "Doe", 30),
};
public void testKVComparators() {
// Comparator<People> cmp = Comparator.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 = Comparator.comparing((Function<People, String>) People::getFirstName);
Comparator<People> cmp2 = Comparator.comparing((Function<People, String>) People::getLastName);
Comparator<People> cmp = cmp1.thenComparing(cmp2);
assertPairComparison(people[0], people[0], people[1], people[1],
Map.Entry.<People, People>comparingByKey(cmp),
Map.Entry.<People, People>comparingByValue(cmp));
}
public void testNulls() {
try {
Comparator<Map.Entry<String, String>> cmp = Map.Entry.comparingByKey(null);
fail("comparingByKey(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
Comparator<Map.Entry<String, String>> cmp = Map.Entry.comparingByValue(null);
fail("comparingByValue(null) should throw NPE");
} catch (NullPointerException npe) {}
}
}
/*
* 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 8009736 8010279
* @run testng BasicTest
*/
import java.util.Comparator;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import org.testng.annotations.Test;
import static java.util.function.BinaryOperator.minBy;
import static java.util.function.BinaryOperator.maxBy;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.fail;
/**
* Unit tests for helper methods in Comparators
*/
@Test(groups = "unit")
public class BasicTest {
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; }
}
private final People people[] = {
new People("John", "Doe", 34),
new People("Mary", "Doe", 30),
};
public void testMaxBy() {
Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName);
// lesser
assertSame(maxBy(cmp).apply(people[0], people[1]), people[1]);
// euqal
cmp = Comparator.comparing((Function<People, String>) People::getLastName);
assertSame(maxBy(cmp).apply(people[0], people[1]), people[0]);
// greater
cmp = Comparator.comparing((ToIntFunction<People>) People::getAge);
assertSame(maxBy(cmp).apply(people[0], people[1]), people[0]);
}
public void testLesserOf() {
Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName);
// lesser
assertSame(minBy(cmp).apply(people[0], people[1]), people[0]);
// euqal
cmp = Comparator.comparing((Function<People, String>) People::getLastName);
assertSame(minBy(cmp).apply(people[0], people[1]), people[0]);
// greater
cmp = Comparator.comparing((ToIntFunction<People>) People::getAge);
assertSame(minBy(cmp).apply(people[0], people[1]), people[1]);
}
public void testNulls() {
try {
BinaryOperator<String> op = minBy(null);
fail("minBy(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
BinaryOperator<String> op = maxBy(null);
fail("maxBy(null) should throw NPE");
} catch (NullPointerException npe) {}
}
}
......@@ -22,7 +22,6 @@
*/
package org.openjdk.tests.java.util.stream;
import java.util.Comparators;
import java.util.stream.LambdaTestHelpers;
import java.util.stream.OpTestCase;
import java.util.stream.StreamTestDataProvider;
......@@ -109,9 +108,9 @@ public class SequentialOpTest extends OpTestCase {
= new UnaryOperator[] {
(UnaryOperator<Stream<Integer>>) s -> s,
(UnaryOperator<Stream<Integer>>) s -> s.map(id),
(UnaryOperator<Stream<Integer>>) s -> s.sorted(Comparators.naturalOrder()),
(UnaryOperator<Stream<Integer>>) s -> s.map(id).sorted(Comparators.naturalOrder()).map(id),
(UnaryOperator<Stream<Integer>>) s -> s.filter(LambdaTestHelpers.pEven).sorted(Comparators.naturalOrder()).map(id),
(UnaryOperator<Stream<Integer>>) s -> s.sorted(Comparator.naturalOrder()),
(UnaryOperator<Stream<Integer>>) s -> s.map(id).sorted(Comparator.naturalOrder()).map(id),
(UnaryOperator<Stream<Integer>>) s -> s.filter(LambdaTestHelpers.pEven).sorted(Comparator.naturalOrder()).map(id),
};
for (int c1Index = 0; c1Index < changers.length; c1Index++) {
......
......@@ -270,7 +270,7 @@ public class SliceOpTest extends OpTestCase {
public void testLimitSort() {
List<Integer> l = countTo(100);
Collections.reverse(l);
exerciseOps(l, s -> s.limit(10).sorted(Comparators.naturalOrder()));
exerciseOps(l, s -> s.limit(10).sorted(Comparator.naturalOrder()));
}
@Test(groups = { "serialization-hostile" })
......
......@@ -40,10 +40,10 @@ public class SortedOpTest extends OpTestCase {
public void testSorted() {
assertCountSum(countTo(0).stream().sorted(), 0, 0);
assertCountSum(countTo(10).stream().sorted(), 10, 55);
assertCountSum(countTo(10).stream().sorted(cInteger.reverseOrder()), 10, 55);
assertCountSum(countTo(10).stream().sorted(cInteger.reversed()), 10, 55);
List<Integer> to10 = countTo(10);
assertSorted(to10.stream().sorted(cInteger.reverseOrder()).iterator(), cInteger.reverseOrder());
assertSorted(to10.stream().sorted(cInteger.reversed()).iterator(), cInteger.reversed());
Collections.reverse(to10);
assertSorted(to10.stream().sorted().iterator());
......@@ -51,7 +51,7 @@ public class SortedOpTest extends OpTestCase {
Spliterator<Integer> s = to10.stream().sorted().spliterator();
assertTrue(s.hasCharacteristics(Spliterator.SORTED));
s = to10.stream().sorted(cInteger.reverseOrder()).spliterator();
s = to10.stream().sorted(cInteger.reversed()).spliterator();
assertFalse(s.hasCharacteristics(Spliterator.SORTED));
}
......@@ -87,8 +87,8 @@ public class SortedOpTest extends OpTestCase {
assertSorted(result.iterator());
assertContentsUnordered(data, result);
result = exerciseOps(data, s -> s.sorted(cInteger.reverseOrder()));
assertSorted(result.iterator(), cInteger.reverseOrder());
result = exerciseOps(data, s -> s.sorted(cInteger.reversed()));
assertSorted(result.iterator(), cInteger.reversed());
assertContentsUnordered(data, result);
}
......@@ -104,23 +104,23 @@ public class SortedOpTest extends OpTestCase {
assertContentsUnordered(data, result);
result = withData(data)
.stream(s -> s.sorted(cInteger.reverseOrder()).sorted(cInteger.reverseOrder()),
.stream(s -> s.sorted(cInteger.reversed()).sorted(cInteger.reversed()),
new CollectorOps.TestParallelSizedOp<Integer>())
.exercise();
assertSorted(result, cInteger.reverseOrder());
assertSorted(result, cInteger.reversed());
assertContentsUnordered(data, result);
result = withData(data)
.stream(s -> s.sorted().sorted(cInteger.reverseOrder()),
.stream(s -> s.sorted().sorted(cInteger.reversed()),
new CollectorOps.TestParallelSizedOp<Integer>())
.exercise();
assertSorted(result, cInteger.reverseOrder());
assertSorted(result, cInteger.reversed());
assertContentsUnordered(data, result);
result = withData(data)
.stream(s -> s.sorted(cInteger.reverseOrder()).sorted(),
.stream(s -> s.sorted(cInteger.reversed()).sorted(),
new CollectorOps.TestParallelSizedOp<Integer>())
.exercise();
......
......@@ -22,7 +22,7 @@
*/
import java.util.Objects;
import java.util.Comparators;
import java.util.Comparator;
import sun.misc.JavaLangAccess;
import sun.misc.SharedSecrets;
......@@ -48,7 +48,7 @@ public class NewUnsafeString {
if (!benchmark.equals(constructorCopy)) {
throw new Error("Copy not equal");
}
if (0 != Objects.compare(benchmark, constructorCopy, Comparators.naturalOrder())) {
if (0 != Objects.compare(benchmark, constructorCopy, Comparator.naturalOrder())) {
throw new Error("Copy not equal");
}
......@@ -58,7 +58,7 @@ public class NewUnsafeString {
if (!benchmark.equals(jlaCopy)) {
throw new Error("Copy not equal");
}
if (0 != Objects.compare(benchmark, jlaCopy, Comparators.naturalOrder())) {
if (0 != Objects.compare(benchmark, jlaCopy, Comparator.naturalOrder())) {
throw new Error("Copy not equal");
}
......@@ -68,7 +68,7 @@ public class NewUnsafeString {
if (!constructorCopy.equals(jlaCopy)) {
throw new Error("Copy not equal");
}
if (0 != Objects.compare(constructorCopy, jlaCopy, Comparators.naturalOrder())) {
if (0 != Objects.compare(constructorCopy, jlaCopy, Comparator.naturalOrder())) {
throw new Error("Copy not equal");
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册