Port java.util.Comparator{,s} from OpenJDK8
Also adds tests for java.util.Comparator API.
Source files are taken from jdk8u60.
Bug: 27427010
Change-Id: Id71eb7fa92c28720c13da8fd0f5f193151b6a43d
diff --git a/luni/src/test/java/libcore/java/util/ComparatorTest.java b/luni/src/test/java/libcore/java/util/ComparatorTest.java
new file mode 100644
index 0000000..a636ea6
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/ComparatorTest.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.java.util;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+public final class ComparatorTest extends TestCase {
+ private static final Item ZERO = new Item(0);
+ private static final Item ONE = new Item(1);
+ private static final Item TWO = new Item(2);
+ private static final Item THREE = new Item(3);
+ private static final Item FOUR = new Item(4);
+
+ private static final Item ZEROZERO = new Item(0, 0);
+ private static final Item ZEROONE = new Item(0, 1);
+ private static final Item ONEZERO = new Item(1, 0);
+ private static final Item ONEONE = new Item(1, 1);
+
+ private static final Item[] orderedItems = new Item[]{ZERO, ONE, TWO, THREE, FOUR};
+ private static final Item[] nullsFirstItems = new Item[]{null, ZERO, ONE, TWO, THREE, FOUR};
+ private static final Item[] nullsLastItems = new Item[]{ZERO, ONE, TWO, THREE, FOUR, null};
+ private static final Item[] orderedItemsMatrix = new Item[]{ZEROZERO, ZEROONE, ONEZERO, ONEONE};
+
+ private <T> void checkComparison(Comparator<T> comparator, T[] items) {
+ for (int i = 0; i < items.length - 1; ++i) {
+ assertEquals(0, comparator.compare(items[i], items[i]));
+ for (int j = i + 1; j < items.length; ++j) {
+ assertTrue(comparator.compare(items[i], items[j]) < 0);
+ assertTrue(comparator.compare(items[j], items[i]) > 0);
+ }
+ }
+ }
+
+ public void testComparingDouble() {
+ Comparator<Item> comparator = Comparator.comparingDouble(Item::getOrderAsDouble);
+ checkComparison(comparator, orderedItems);
+ }
+
+ public void testComparingInt() {
+ Comparator<Item> comparator = Comparator.comparingInt(Item::getOrderAsInt);
+ checkComparison(comparator, orderedItems);
+ }
+
+ public void testComparingLong() {
+ Comparator<Item> comparator = Comparator.comparingLong(Item::getOrderAsLong);
+ checkComparison(comparator, orderedItems);
+ }
+
+ public void testComparing() {
+ Comparator<Item> comparator = Comparator.comparing(Item::getOrderAsString);
+ checkComparison(comparator, orderedItems);
+ }
+
+ public void testComparing2() {
+ Comparator<Item> comparator = Comparator.comparing(Item::getOrderAsString,
+ String.CASE_INSENSITIVE_ORDER);
+ checkComparison(comparator, orderedItems);
+ }
+
+ public void testNaturalOrder() {
+ Comparator<Item> comparator = Comparator.naturalOrder();
+ checkComparison(comparator, orderedItems);
+ checkComparison(comparator, orderedItemsMatrix);
+ }
+
+ public void testReverseOrder() {
+ List<Item> itemsList = Arrays.asList(orderedItems);
+ Collections.reverse(itemsList);
+ Comparator<Item> comparator = Comparator.reverseOrder();
+ checkComparison(comparator, (Item[]) itemsList.toArray());
+ }
+
+ public void testReverse() {
+ Comparator<Item> revComparator = Comparator.reverseOrder();
+ Comparator<Item> revRevComparator = revComparator.reversed();
+ checkComparison(revRevComparator, orderedItems);
+ checkComparison(revRevComparator, orderedItemsMatrix);
+ }
+
+ public void testReverse2() {
+ Comparator<Item> comparator = Comparator.naturalOrder();
+ assertSame(comparator, comparator.reversed().reversed());
+ }
+
+ public void testReverse3() {
+ Comparator<Item> comparator = Comparator.comparing(Item::getOrderAsString);
+ assertSame(comparator, comparator.reversed().reversed());
+ }
+
+ public void testNullsFirst() {
+ Comparator<Item> comparator = Comparator.nullsFirst(Comparator.naturalOrder());
+ checkComparison(comparator, nullsFirstItems);
+ }
+
+ public void testNullsLast() {
+ Comparator<Item> comparator = Comparator.nullsLast(Comparator.naturalOrder());
+ checkComparison(comparator, nullsLastItems);
+ }
+
+ public void testThenComparingDouble() {
+ Comparator<Item> comparator = Comparator.comparingDouble(Item::getOrderAsDouble)
+ .thenComparingDouble(Item::getSecondaryOrderAsDouble);
+ checkComparison(comparator, orderedItemsMatrix);
+ }
+
+ public void testThenComparingInt() {
+ Comparator<Item> comparator = Comparator.comparingInt(Item::getOrderAsInt)
+ .thenComparingInt(Item::getSecondaryOrderAsInt);
+ checkComparison(comparator, orderedItemsMatrix);
+ }
+
+ public void testThenComparingLong() {
+ Comparator<Item> comparator = Comparator.comparingLong(Item::getOrderAsLong)
+ .thenComparingLong(Item::getSecondaryOrderAsLong);
+ checkComparison(comparator, orderedItemsMatrix);
+ }
+
+ public void testThenComparing() {
+ Comparator<Item> comparator = Comparator.comparing(Item::getOrderAsString)
+ .thenComparing(Item::getSecondaryOrderAsString);
+ checkComparison(comparator, orderedItemsMatrix);
+ }
+
+ private static final class Item implements Comparable<Item> {
+ private final int primaryOrder;
+ private final int secondaryOrder;
+
+ public Item(int primaryOrder) {
+ this(primaryOrder, 0);
+ }
+
+ public Item(int primaryOrder, int secondaryOrder) {
+ this.primaryOrder = primaryOrder;
+ this.secondaryOrder = secondaryOrder;
+ }
+
+ public Integer getOrderAsInt() {
+ return primaryOrder;
+ }
+
+ public Long getOrderAsLong() {
+ return Long.valueOf(primaryOrder);
+ }
+
+ public Double getOrderAsDouble() {
+ return Double.valueOf(primaryOrder);
+ }
+
+ public String getOrderAsString() {
+ return String.valueOf(primaryOrder);
+ }
+
+ public Integer getSecondaryOrderAsInt() {
+ return secondaryOrder;
+ }
+
+ public Long getSecondaryOrderAsLong() {
+ return Long.valueOf(secondaryOrder);
+ }
+
+ public Double getSecondaryOrderAsDouble() {
+ return Double.valueOf(secondaryOrder);
+ }
+
+ public String getSecondaryOrderAsString() {
+ return String.valueOf(secondaryOrder);
+ }
+
+ @Override
+ public int compareTo(Item other) {
+ return primaryOrder - other.getOrderAsInt() != 0 ?
+ primaryOrder - other.getOrderAsInt() :
+ secondaryOrder - other.getSecondaryOrderAsInt();
+ }
+ }
+
+}
diff --git a/ojluni/src/lambda/java/java/lang/invoke/SerializedLambda.java b/ojluni/src/lambda/java/java/lang/invoke/SerializedLambda.java
new file mode 100644
index 0000000..55ec670
--- /dev/null
+++ b/ojluni/src/lambda/java/java/lang/invoke/SerializedLambda.java
@@ -0,0 +1,82 @@
+/*
+ * 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
+ * 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.lang.invoke;
+
+import java.io.Serializable;
+
+public final class SerializedLambda implements Serializable {
+
+ public SerializedLambda(Class<?> capturingClass,
+ String functionalInterfaceClass,
+ String functionalInterfaceMethodName,
+ String functionalInterfaceMethodSignature,
+ int implMethodKind,
+ String implClass,
+ String implMethodName,
+ String implMethodSignature,
+ String instantiatedMethodType,
+ Object[] capturedArgs) { }
+
+ public String getCapturingClass() { return null; }
+
+ public String getFunctionalInterfaceClass() {
+ return null;
+ }
+
+ public String getFunctionalInterfaceMethodName() {
+ return null;
+ }
+
+ public String getFunctionalInterfaceMethodSignature() { return null; }
+
+ public String getImplClass() {
+ return null;
+ }
+
+ public String getImplMethodName() {
+ return null;
+ }
+
+ public String getImplMethodSignature() {
+ return null;
+ }
+
+ public int getImplMethodKind() {
+ return 0;
+ }
+
+ public final String getInstantiatedMethodType() {
+ return null;
+ }
+
+ public int getCapturedArgCount() {
+ return 0;
+ }
+
+ public Object getCapturedArg(int i) {
+ return null;
+ }
+
+}
diff --git a/ojluni/src/main/java/java/util/Collections.java b/ojluni/src/main/java/java/util/Collections.java
index 65fbce6..47a1ecc 100755
--- a/ojluni/src/main/java/java/util/Collections.java
+++ b/ojluni/src/main/java/java/util/Collections.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -3707,6 +3707,11 @@
}
private Object readResolve() { return reverseOrder(); }
+
+ @Override
+ public Comparator<Comparable<Object>> reversed() {
+ return Comparator.naturalOrder();
+ }
}
/**
@@ -3770,6 +3775,11 @@
public int hashCode() {
return cmp.hashCode() ^ Integer.MIN_VALUE;
}
+
+ @Override
+ public Comparator<T> reversed() {
+ return cmp;
+ }
}
/**
diff --git a/ojluni/src/main/java/java/util/Comparator.java b/ojluni/src/main/java/java/util/Comparator.java
old mode 100755
new mode 100644
index 453e9b7..ecf8d64
--- a/ojluni/src/main/java/java/util/Comparator.java
+++ b/ojluni/src/main/java/java/util/Comparator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -25,6 +25,13 @@
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
* collection of objects. Comparators can be passed to a sort method (such
@@ -98,7 +105,7 @@
* @see java.io.Serializable
* @since 1.2
*/
-
+@FunctionalInterface
public interface Comparator<T> {
/**
* Compares its two arguments for order. Returns a negative integer,
@@ -165,4 +172,363 @@
* @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> reversed() {
+ return Collections.reverseOrder(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.comparingInt(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) {
+ Objects.requireNonNull(other);
+ return (Comparator<T> & Serializable) (c1, c2) -> {
+ int res = compare(c1, c2);
+ return (res != 0) ? res : other.compare(c1, c2);
+ };
+ }
+
+ /**
+ * 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 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 either argument is null.
+ * @see #comparing(Function, Comparator)
+ * @see #thenComparing(Comparator)
+ * @since 1.8
+ */
+ default <U> Comparator<T> thenComparing(
+ Function<? super T, ? extends U> keyExtractor,
+ Comparator<? super U> keyComparator)
+ {
+ return thenComparing(comparing(keyExtractor, keyComparator));
+ }
+
+ /**
+ * 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 <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 #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(comparingInt(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 #comparingInt(ToIntFunction)
+ * @see #thenComparing(Comparator)
+ * @since 1.8
+ */
+ default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {
+ return thenComparing(comparingInt(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(comparingLong(keyExtractor))}.
+ *
+ * @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 #comparingLong(ToLongFunction)
+ * @see #thenComparing(Comparator)
+ * @since 1.8
+ */
+ default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {
+ return thenComparing(comparingLong(keyExtractor));
+ }
+
+ /**
+ * Returns a lexicographic-order comparator with a function that
+ * extracts a {@code double} sort key.
+ *
+ * @implSpec This default implementation behaves as if {@code
+ * thenComparing(comparingDouble(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 #comparingDouble(ToDoubleFunction)
+ * @see #thenComparing(Comparator)
+ * @since 1.8
+ */
+ default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {
+ return thenComparing(comparingDouble(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
+ */
+ @SuppressWarnings("unchecked")
+ 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> comparingInt(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> comparingLong(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> comparingDouble(ToDoubleFunction<? super T> keyExtractor) {
+ Objects.requireNonNull(keyExtractor);
+ return (Comparator<T> & Serializable)
+ (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
+ }
}
diff --git a/ojluni/src/main/java/java/util/Comparators.java b/ojluni/src/main/java/java/util/Comparators.java
new file mode 100644
index 0000000..ee80679
--- /dev/null
+++ b/ojluni/src/main/java/java/util/Comparators.java
@@ -0,0 +1,98 @@
+/*
+ * 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
+ * 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;
+
+/**
+ * Package private supporting class for {@link Comparator}.
+ */
+class Comparators {
+ private Comparators() {
+ throw new AssertionError("no instances");
+ }
+
+ /**
+ * Compares {@link Comparable} objects in natural order.
+ *
+ * @see Comparable
+ */
+ enum NaturalOrderComparator implements Comparator<Comparable<Object>> {
+ INSTANCE;
+
+ @Override
+ public int compare(Comparable<Object> c1, Comparable<Object> c2) {
+ return c1.compareTo(c2);
+ }
+
+ @Override
+ public Comparator<Comparable<Object>> reversed() {
+ return Comparator.reverseOrder();
+ }
+ }
+
+ /**
+ * Null-friendly comparators
+ */
+ 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;
+ }
+
+ @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);
+ }
+ }
+
+ @Override
+ public Comparator<T> thenComparing(Comparator<? super T> other) {
+ Objects.requireNonNull(other);
+ return new NullComparator<>(nullFirst, real == null ? other : real.thenComparing(other));
+ }
+
+ @Override
+ public Comparator<T> reversed() {
+ return new NullComparator<>(!nullFirst, real == null ? null : real.reversed());
+ }
+ }
+}
diff --git a/openjdk_java_files.mk b/openjdk_java_files.mk
index fc69ca4..fd0eebf 100644
--- a/openjdk_java_files.mk
+++ b/openjdk_java_files.mk
@@ -655,6 +655,7 @@
ojluni/src/main/java/java/util/Collections.java \
ojluni/src/main/java/java/util/ComparableTimSort.java \
ojluni/src/main/java/java/util/Comparator.java \
+ ojluni/src/main/java/java/util/Comparators.java \
ojluni/src/main/java/java/util/ConcurrentModificationException.java \
ojluni/src/main/java/java/util/Currency.java \
ojluni/src/main/java/java/util/Date.java \
@@ -1472,3 +1473,4 @@
ojluni/src/lambda/java/java/lang/invoke/MethodHandleInfo.java \
ojluni/src/lambda/java/java/lang/invoke/MethodHandles.java \
ojluni/src/lambda/java/java/lang/invoke/MethodType.java \
+ ojluni/src/lambda/java/java/lang/invoke/SerializedLambda.java