Path: blob/master/test/jdk/java/util/Comparator/BasicTest.java
41149 views
/*1* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* @test25* @bug 817182626* @summary Comparator default method tests27* @run testng BasicTest28*/2930import org.testng.annotations.Test;3132import java.util.Collections;33import java.util.Comparator;34import java.util.function.Function;35import java.util.function.ToDoubleFunction;36import java.util.function.ToIntFunction;37import java.util.function.ToLongFunction;3839import static org.testng.Assert.*;4041@Test(groups = "unit")42public class BasicTest {43private static class Thing {44public final int intField;45public final long longField;46public final double doubleField;47public final String stringField;4849private Thing(int intField, long longField, double doubleField, String stringField) {50this.intField = intField;51this.longField = longField;52this.doubleField = doubleField;53this.stringField = stringField;54}5556public int getIntField() {57return intField;58}5960public long getLongField() {61return longField;62}6364public double getDoubleField() {65return doubleField;66}6768public String getStringField() {69return stringField;70}71}7273private final int[] intValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };74private final long[] longValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };75private final double[] doubleValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };76private final String[] stringValues = { "a", "a", "b", "b", "c", "c", "d", "d", "e", "e" };77private final int[] comparisons = { 0, -1, 0, -1, 0, -1, 0, -1, 0 };7879private<T> void assertComparisons(T[] things, Comparator<T> comp, int[] comparisons) {80for (int i=0; i<comparisons.length; i++) {81assertEquals(comparisons.length + 1, things.length);82assertEquals(comparisons[i], comp.compare(things[i], things[i+1]));83assertEquals(-comparisons[i], comp.compare(things[i+1], things[i]));84}85}8687public void testIntComparator() {88Thing[] things = new Thing[intValues.length];89for (int i=0; i<intValues.length; i++)90things[i] = new Thing(intValues[i], 0L, 0.0, null);91Comparator<Thing> comp = Comparator.comparingInt(new ToIntFunction<Thing>() {92@Override93public int applyAsInt(Thing thing) {94return thing.getIntField();95}96});9798assertComparisons(things, comp, comparisons);99}100101public void testLongComparator() {102Thing[] things = new Thing[longValues.length];103for (int i=0; i<longValues.length; i++)104things[i] = new Thing(0, longValues[i], 0.0, null);105Comparator<Thing> comp = Comparator.comparingLong(new ToLongFunction<Thing>() {106@Override107public long applyAsLong(Thing thing) {108return thing.getLongField();109}110});111112assertComparisons(things, comp, comparisons);113}114115public void testDoubleComparator() {116Thing[] things = new Thing[doubleValues.length];117for (int i=0; i<doubleValues.length; i++)118things[i] = new Thing(0, 0L, doubleValues[i], null);119Comparator<Thing> comp = Comparator.comparingDouble(new ToDoubleFunction<Thing>() {120@Override121public double applyAsDouble(Thing thing) {122return thing.getDoubleField();123}124});125126assertComparisons(things, comp, comparisons);127}128129public void testComparing() {130Thing[] things = new Thing[doubleValues.length];131for (int i=0; i<doubleValues.length; i++)132things[i] = new Thing(0, 0L, 0.0, stringValues[i]);133Comparator<Thing> comp = Comparator.comparing(new Function<Thing, String>() {134@Override135public String apply(Thing thing) {136return thing.getStringField();137}138});139140assertComparisons(things, comp, comparisons);141}142143public void testNaturalOrderComparator() {144Comparator<String> comp = Comparator.naturalOrder();145146assertComparisons(stringValues, comp, comparisons);147}148149public void testReverseComparator() {150Comparator<String> cmpr = Comparator.reverseOrder();151Comparator<String> cmp = cmpr.reversed();152153assertEquals(cmp.reversed(), cmpr);154assertEquals(0, cmp.compare("a", "a"));155assertEquals(0, cmpr.compare("a", "a"));156assertTrue(cmp.compare("a", "b") < 0);157assertTrue(cmpr.compare("a", "b") > 0);158assertTrue(cmp.compare("b", "a") > 0);159assertTrue(cmpr.compare("b", "a") < 0);160}161162public void testReverseComparator2() {163Comparator<String> cmp = (s1, s2) -> s1.length() - s2.length();164Comparator<String> cmpr = cmp.reversed();165166assertEquals(cmpr.reversed(), cmp);167assertEquals(0, cmp.compare("abc", "def"));168assertEquals(0, cmpr.compare("abc", "def"));169assertTrue(cmp.compare("abcd", "def") > 0);170assertTrue(cmpr.compare("abcd", "def") < 0);171assertTrue(cmp.compare("abc", "defg") < 0);172assertTrue(cmpr.compare("abc", "defg") > 0);173}174175private <T> void assertComparison(Comparator<T> cmp, T less, T greater) {176assertTrue(cmp.compare(less, greater) < 0, "less");177assertTrue(cmp.compare(less, less) == 0, "equal");178assertTrue(cmp.compare(greater, greater) == 0, "equal");179assertTrue(cmp.compare(greater, less) > 0, "greater");180}181182private static class People {183final String firstName;184final String lastName;185final int age;186187People(String first, String last, int age) {188firstName = first;189lastName = last;190this.age = age;191}192193String getFirstName() { return firstName; }194String getLastName() { return lastName; }195int getAge() { return age; }196long getAgeAsLong() { return (long) age; };197double getAgeAsDouble() { return (double) age; };198}199200private final People people[] = {201new People("John", "Doe", 34),202new People("Mary", "Doe", 30),203new People("Maria", "Doe", 14),204new People("Jonah", "Doe", 10),205new People("John", "Cook", 54),206new People("Mary", "Cook", 50),207new People("Mary", null, 25),208new People("John", null, 27)209};210211public void testComparatorDefaultMethods() {212Comparator<People> cmp = Comparator.comparing(People::getFirstName);213Comparator<People> cmp2 = Comparator.comparing(People::getLastName);214// reverseOrder215assertComparison(cmp.reversed(), people[1], people[0]);216// thenComparing(Comparator)217assertComparison(cmp.thenComparing(cmp2), people[0], people[1]);218assertComparison(cmp.thenComparing(cmp2), people[4], people[0]);219// thenComparing(Function)220assertComparison(cmp.thenComparing(People::getLastName), people[0], people[1]);221assertComparison(cmp.thenComparing(People::getLastName), people[4], people[0]);222// thenComparing(ToIntFunction)223assertComparison(cmp.thenComparingInt(People::getAge), people[0], people[1]);224assertComparison(cmp.thenComparingInt(People::getAge), people[1], people[5]);225// thenComparing(ToLongFunction)226assertComparison(cmp.thenComparingLong(People::getAgeAsLong), people[0], people[1]);227assertComparison(cmp.thenComparingLong(People::getAgeAsLong), people[1], people[5]);228// thenComparing(ToDoubleFunction)229assertComparison(cmp.thenComparingDouble(People::getAgeAsDouble), people[0], people[1]);230assertComparison(cmp.thenComparingDouble(People::getAgeAsDouble), people[1], people[5]);231}232233234public void testNullsFirst() {235Comparator<String> strcmp = Comparator.nullsFirst(Comparator.naturalOrder());236Comparator<People> cmp = Comparator.comparing(People::getLastName, strcmp)237.thenComparing(People::getFirstName, strcmp);238// Mary.null vs Mary.Cook - solve by last name239assertComparison(cmp, people[6], people[5]);240// John.null vs Mary.null - solve by first name241assertComparison(cmp, people[7], people[6]);242243// More than one thenComparing244strcmp = Comparator.nullsFirst(Comparator.comparingInt(String::length)245.thenComparing(String.CASE_INSENSITIVE_ORDER));246assertComparison(strcmp, null, "abc");247assertComparison(strcmp, "ab", "abc");248assertComparison(strcmp, "abc", "def");249assertEquals(0, strcmp.compare("abc", "ABC"));250251// Ensure reverse still handle null properly252Comparator<String> strcmp2 = strcmp.reversed().thenComparing(Comparator.naturalOrder());253assertComparison(strcmp2, "abc", null);254assertComparison(strcmp2, "abc", "ab");255assertComparison(strcmp2, "def", "abc");256assertComparison(strcmp2, "ABC", "abc");257258// Considering non-null values to be equal259Comparator<String> blind = Comparator.nullsFirst(null);260assertComparison(blind, null, "abc");261assertEquals(0, blind.compare("abc", "def"));262// reverse still consider non-null values to be equal263strcmp = blind.reversed();264assertComparison(strcmp, "abc", null);265assertEquals(0, strcmp.compare("abc", "def"));266// chain with another comparator to compare non-nulls267strcmp = blind.thenComparing(Comparator.naturalOrder());268assertComparison(strcmp, null, "abc");269assertComparison(strcmp, "abc", "def");270}271272public void testNullsLast() {273Comparator<String> strcmp = Comparator.nullsLast(Comparator.naturalOrder());274Comparator<People> cmp = Comparator.comparing(People::getLastName, strcmp)275.thenComparing(People::getFirstName, strcmp);276// Mary.null vs Mary.Cook - solve by last name277assertComparison(cmp, people[5], people[6]);278// John.null vs Mary.null - solve by first name279assertComparison(cmp, people[7], people[6]);280281// More than one thenComparing282strcmp = Comparator.nullsLast(Comparator.comparingInt(String::length)283.thenComparing(String.CASE_INSENSITIVE_ORDER));284assertComparison(strcmp, "abc", null);285assertComparison(strcmp, "ab", "abc");286assertComparison(strcmp, "abc", "def");287288// Ensure reverse still handle null properly289Comparator<String> strcmp2 = strcmp.reversed().thenComparing(Comparator.naturalOrder());290assertComparison(strcmp2, null, "abc");291assertComparison(strcmp2, "abc", "ab");292assertComparison(strcmp2, "def", "abc");293assertComparison(strcmp2, "ABC", "abc");294295// Considering non-null values to be equal296Comparator<String> blind = Comparator.nullsLast(null);297assertComparison(blind, "abc", null);298assertEquals(0, blind.compare("abc", "def"));299// reverse still consider non-null values to be equal300strcmp = blind.reversed();301assertComparison(strcmp, null, "abc");302assertEquals(0, strcmp.compare("abc", "def"));303// chain with another comparator to compare non-nulls304strcmp = blind.thenComparing(Comparator.naturalOrder());305assertComparison(strcmp, "abc", null);306assertComparison(strcmp, "abc", "def");307}308309public void testComposeComparator() {310// Longer string in front311Comparator<String> first = (s1, s2) -> s2.length() - s1.length();312Comparator<String> second = Comparator.naturalOrder();313Comparator<String> composed = first.thenComparing(second);314315assertTrue(composed.compare("abcdefg", "abcdef") < 0);316assertTrue(composed.compare("abcdef", "abcdefg") > 0);317assertTrue(composed.compare("abcdef", "abcdef") == 0);318assertTrue(composed.compare("abcdef", "ghijkl") < 0);319assertTrue(composed.compare("ghijkl", "abcdefg") > 0);320}321322public void testNulls() {323try {324Comparator.<String>naturalOrder().compare("abc", (String) null);325fail("expected NPE with naturalOrder");326} catch (NullPointerException npe) {}327try {328Comparator.<String>naturalOrder().compare((String) null, "abc");329fail("expected NPE with naturalOrder");330} catch (NullPointerException npe) {}331332try {333Comparator.<String>reverseOrder().compare("abc", (String) null);334fail("expected NPE with naturalOrder");335} catch (NullPointerException npe) {}336try {337Comparator.<String>reverseOrder().compare((String) null, "abc");338fail("expected NPE with naturalOrder");339} catch (NullPointerException npe) {}340341try {342Comparator<People> cmp = Comparator.comparing(null, Comparator.<String>naturalOrder());343fail("comparing(null, cmp) should throw NPE");344} catch (NullPointerException npe) {}345try {346Comparator<People> cmp = Comparator.comparing(People::getFirstName, null);347fail("comparing(f, null) should throw NPE");348} catch (NullPointerException npe) {}349350try {351Comparator<People> cmp = Comparator.comparing(null);352fail("comparing(null) should throw NPE");353} catch (NullPointerException npe) {}354try {355Comparator<People> cmp = Comparator.comparingInt(null);356fail("comparing(null) should throw NPE");357} catch (NullPointerException npe) {}358try {359Comparator<People> cmp = Comparator.comparingLong(null);360fail("comparing(null) should throw NPE");361} catch (NullPointerException npe) {}362try {363Comparator<People> cmp = Comparator.comparingDouble(null);364fail("comparing(null) should throw NPE");365} catch (NullPointerException npe) {}366}367368public void testNaturalAndReverseIdentity() {369var naturalOrder = Comparator.<String>naturalOrder();370var reverseOrder = Comparator.<String>reverseOrder();371372assertEquals(373naturalOrder,374Collections.reverseOrder(reverseOrder),375"Comparator.naturalOrder() and Collections.reverseOrder(Comparator.reverseOrder()) not equal");376377assertEquals(378reverseOrder,379Collections.reverseOrder(naturalOrder),380"Comparator.reverseOrder() and Collections.reverseOrder(Comparator.naturalOrder()) not equal");381382assertEquals(383naturalOrder.reversed(),384reverseOrder,385"Comparator.naturalOrder().reversed() amd Comparator.reverseOrder() not equal");386387assertEquals(388reverseOrder.reversed(),389naturalOrder,390"Comparator.reverseOrder().reversed() and Comparator.naturalOrder() not equal");391}392}393394395