/*
* Copyright ( c ) 2013 , 2017 , 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 8171826
* @ summary Comparator default method tests
* @ run testng BasicTest
*/
import org.testng.annotations.Test;
import java.util.Collections;
import java.util.Comparator;
import java.util.function .Function ;
import java.util.function .ToDoubleFunction;
import java.util.function .ToIntFunction;
import java.util.function .ToLongFunction;
import static org.testng.Assert .*;
@Test(groups = "unit" )
public class BasicTest {
private static class Thing {
public final int intField;
public final long longField;
public final double doubleField;
public final String stringField;
private Thing(int intField, long longField, double doubleField, String stringField) {
this .intField = intField;
this .longField = longField;
this .doubleField = doubleField;
this .stringField = stringField;
}
public int getIntField() {
return intField;
}
public long getLongField() {
return longField;
}
public double getDoubleField() {
return doubleField;
}
public String getStringField() {
return stringField;
}
}
private final int [] intValues = { -2 , -2 , -1 , -1 , 0 , 0 , 1 , 1 , 2 , 2 };
private final long [] longValues = { -2 , -2 , -1 , -1 , 0 , 0 , 1 , 1 , 2 , 2 };
private final double [] doubleValues = { -2 , -2 , -1 , -1 , 0 , 0 , 1 , 1 , 2 , 2 };
private final String[] stringValues = { "a" , "a" , "b" , "b" , "c" , "c" , "d" , "d" , "e" , "e" };
private final int [] comparisons = { 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 };
private <T> void assertComparisons(T[] things, Comparator<T> comp, int [] comparisons) {
for (int i=0 ; i<comparisons.length; i++) {
assertEquals(comparisons.length + 1 , things.length);
assertEquals(comparisons[i], comp.compare(things[i], things[i+1 ]));
assertEquals(-comparisons[i], comp.compare(things[i+1 ], things[i]));
}
}
public void testIntComparator() {
Thing[] things = new Thing[intValues.length];
for (int i=0 ; i<intValues.length; i++)
things[i] = new Thing(intValues[i], 0 L, 0 .0 , null );
Comparator<Thing> comp = Comparator.comparingInt(new ToIntFunction<Thing>() {
@Override
public int applyAsInt(Thing thing) {
return thing.getIntField();
}
});
assertComparisons(things, comp, comparisons);
}
public void testLongComparator() {
Thing[] things = new Thing[longValues.length];
for (int i=0 ; i<longValues.length; i++)
things[i] = new Thing(0 , longValues[i], 0 .0 , null );
Comparator<Thing> comp = Comparator.comparingLong(new ToLongFunction<Thing>() {
@Override
public long applyAsLong(Thing thing) {
return thing.getLongField();
}
});
assertComparisons(things, comp, comparisons);
}
public void testDoubleComparator() {
Thing[] things = new Thing[doubleValues.length];
for (int i=0 ; i<doubleValues.length; i++)
things[i] = new Thing(0 , 0 L, doubleValues[i], null );
Comparator<Thing> comp = Comparator.comparingDouble(new ToDoubleFunction<Thing>() {
@Override
public double applyAsDouble(Thing thing) {
return thing.getDoubleField();
}
});
assertComparisons(things, comp, comparisons);
}
public void testComparing() {
Thing[] things = new Thing[doubleValues.length];
for (int i=0 ; i<doubleValues.length; i++)
things[i] = new Thing(0 , 0 L, 0 .0 , stringValues[i]);
Comparator<Thing> comp = Comparator.comparing(new Function <Thing, String>() {
@Override
public String apply(Thing thing) {
return thing.getStringField();
}
});
assertComparisons(things, comp, comparisons);
}
public void testNaturalOrderComparator() {
Comparator<String> comp = Comparator.naturalOrder();
assertComparisons(stringValues, comp, comparisons);
}
public void testReverseComparator() {
Comparator<String> cmpr = Comparator.reverseOrder();
Comparator<String> cmp = cmpr.reversed();
assertEquals(cmp.reversed(), cmpr);
assertEquals(0 , cmp.compare("a" , "a" ));
assertEquals(0 , cmpr.compare("a" , "a" ));
assertTrue(cmp.compare("a" , "b" ) < 0 );
assertTrue(cmpr.compare("a" , "b" ) > 0 );
assertTrue(cmp.compare("b" , "a" ) > 0 );
assertTrue(cmpr.compare("b" , "a" ) < 0 );
}
public void testReverseComparator2() {
Comparator<String> cmp = (s1, s2) -> s1.length() - s2.length();
Comparator<String> cmpr = cmp.reversed();
assertEquals(cmpr.reversed(), cmp);
assertEquals(0 , cmp.compare("abc" , "def" ));
assertEquals(0 , cmpr.compare("abc" , "def" ));
assertTrue(cmp.compare("abcd" , "def" ) > 0 );
assertTrue(cmpr.compare("abcd" , "def" ) < 0 );
assertTrue(cmp.compare("abc" , "defg" ) < 0 );
assertTrue(cmpr.compare("abc" , "defg" ) > 0 );
}
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 {
final String firstName;
final String lastName;
final int age;
People(String first, String last, int age) {
firstName = first;
lastName = last;
this .age = age;
}
String getFirstName() { return firstName; }
String getLastName() { return lastName; }
int getAge() { return age; }
long getAgeAsLong() { return (long ) age; };
double getAgeAsDouble() { return (double ) age; };
}
private final People people[] = {
new People("John" , "Doe" , 34 ),
new People("Mary" , "Doe" , 30 ),
new People("Maria" , "Doe" , 14 ),
new People("Jonah" , "Doe" , 10 ),
new People("John" , "Cook" , 54 ),
new People("Mary" , "Cook" , 50 ),
new People("Mary" , null , 25 ),
new People("John" , null , 27 )
};
public void testComparatorDefaultMethods() {
Comparator<People> cmp = Comparator.comparing(People::getFirstName);
Comparator<People> cmp2 = Comparator.comparing(People::getLastName);
// reverseOrder
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 ]);
// thenComparing(Function)
assertComparison(cmp.thenComparing(People::getLastName), people[0 ], people[1 ]);
assertComparison(cmp.thenComparing(People::getLastName), people[4 ], people[0 ]);
// thenComparing(ToIntFunction)
assertComparison(cmp.thenComparingInt(People::getAge), people[0 ], people[1 ]);
assertComparison(cmp.thenComparingInt(People::getAge), people[1 ], people[5 ]);
// thenComparing(ToLongFunction)
assertComparison(cmp.thenComparingLong(People::getAgeAsLong), people[0 ], people[1 ]);
assertComparison(cmp.thenComparingLong(People::getAgeAsLong), people[1 ], people[5 ]);
// thenComparing(ToDoubleFunction)
assertComparison(cmp.thenComparingDouble(People::getAgeAsDouble), people[0 ], people[1 ]);
assertComparison(cmp.thenComparingDouble(People::getAgeAsDouble), people[1 ], people[5 ]);
}
public void testNullsFirst() {
Comparator<String> strcmp = Comparator.nullsFirst(Comparator.naturalOrder());
Comparator<People> cmp = Comparator.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.comparingInt(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.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.comparingInt(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 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 {
Comparator.<String>naturalOrder().compare("abc" , (String) null );
fail("expected NPE with naturalOrder" );
} catch (NullPointerException npe) {}
try {
Comparator.<String>naturalOrder().compare((String) null , "abc" );
fail("expected NPE with naturalOrder" );
} catch (NullPointerException npe) {}
try {
Comparator.<String>reverseOrder().compare("abc" , (String) null );
fail("expected NPE with naturalOrder" );
} catch (NullPointerException npe) {}
try {
Comparator.<String>reverseOrder().compare((String) null , "abc" );
fail("expected NPE with naturalOrder" );
} catch (NullPointerException npe) {}
try {
Comparator<People> cmp = Comparator.comparing(null , Comparator.<String>naturalOrder());
fail("comparing(null, cmp) should throw NPE" );
} catch (NullPointerException npe) {}
try {
Comparator<People> cmp = Comparator.comparing(People::getFirstName, null );
fail("comparing(f, null) should throw NPE" );
} catch (NullPointerException npe) {}
try {
Comparator<People> cmp = Comparator.comparing(null );
fail("comparing(null) should throw NPE" );
} catch (NullPointerException npe) {}
try {
Comparator<People> cmp = Comparator.comparingInt(null );
fail("comparing(null) should throw NPE" );
} catch (NullPointerException npe) {}
try {
Comparator<People> cmp = Comparator.comparingLong(null );
fail("comparing(null) should throw NPE" );
} catch (NullPointerException npe) {}
try {
Comparator<People> cmp = Comparator.comparingDouble(null );
fail("comparing(null) should throw NPE" );
} catch (NullPointerException npe) {}
}
public void testNaturalAndReverseIdentity() {
var naturalOrder = Comparator.<String>naturalOrder();
var reverseOrder = Comparator.<String>reverseOrder();
assertEquals(
naturalOrder,
Collections.reverseOrder(reverseOrder),
"Comparator.naturalOrder() and Collections.reverseOrder(Comparator.reverseOrder()) not equal" );
assertEquals(
reverseOrder,
Collections.reverseOrder(naturalOrder),
"Comparator.reverseOrder() and Collections.reverseOrder(Comparator.naturalOrder()) not equal" );
assertEquals(
naturalOrder.reversed(),
reverseOrder,
"Comparator.naturalOrder().reversed() amd Comparator.reverseOrder() not equal" );
assertEquals(
reverseOrder.reversed(),
naturalOrder,
"Comparator.reverseOrder().reversed() and Comparator.naturalOrder() not equal" );
}
}
Messung V0.5 in Prozent C=92 H=89 G=90
¤ Dauer der Verarbeitung: 0.7 Sekunden
¤
*© Formatika GbR, Deutschland