1/* 2 * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/** 25 * @test 26 * @summary Comparator API narrowing type test 27 * @bug 8009736 8033590 28 * @run testng TypeTest 29 */ 30 31import java.util.function.Function; 32import java.util.Map; 33import java.util.TreeMap; 34import java.util.Comparator; 35import org.testng.annotations.Test; 36 37import static org.testng.Assert.assertTrue; 38 39@Test(groups = "unit") 40public class TypeTest { 41 static class Person { 42 String name; 43 static Comparator<Person> C = (p1, p2) -> p1.name.compareTo(p2.name); 44 45 Person(String name) { 46 this.name = name; 47 } 48 49 String getName() { return name; } 50 } 51 52 static class Employee extends Person { 53 int id; 54 static Comparator<Employee> C = (e1, e2) -> e1.id - e2.id; 55 56 Employee(int id, String name) { 57 super(name); 58 this.id = id; 59 } 60 } 61 62 static class Manager extends Employee { 63 long reports; 64 static Comparator<Manager> C = (e1, e2) -> (int) (e1.reports - e2.reports); 65 66 Manager(String name, int id, long reports) { 67 super(id, name); 68 this.reports = reports; 69 } 70 } 71 72 static class Department { 73 Manager mgr; 74 String hr_code; 75 76 Department(Manager mgr, String hr) { 77 this.mgr = mgr; 78 this.hr_code = hr; 79 } 80 81 Manager getManager() { 82 return mgr; 83 } 84 85 String getHR() { 86 return hr_code; 87 } 88 } 89 90 static <T> void assertOrder(T o1, T o2, Comparator<? super T> cmp) { 91 if (cmp.compare(o1, o2) > 0) { 92 System.out.println("Fail!!"); 93 } 94 if (cmp.compare(o1, o2) == 0) { 95 System.out.println("Equal!!"); 96 } 97 } 98 99 // Type tests just to make sure the code can compile and build 100 // Not necessarily need a meaningful result 101 public void testOrder() { 102 Manager m1 = new Manager("Manager", 2, 2000); 103 Manager m2 = new Manager("Manager", 4, 1300); 104 105 // Comparator<Employee> tmp = Person.C; 106 107 // Comparator<Manager> cmp = Employee.C.thenComparing(Person.C); 108 Comparator<Employee> cmp = Employee.C.thenComparing(Person.C); 109 assertOrder(m1, m2, Employee.C.thenComparing(Person.C)); 110 assertOrder(m1, m2, cmp); 111 assertOrder(m1, new Employee(1, "Z"), Person.C); 112 assertOrder(new Employee(1, "Z"), m2, Employee.C); 113 114 assertOrder(m1, m2, Comparator.comparing(Employee::getName, String.CASE_INSENSITIVE_ORDER)); 115 116 Map<String, Integer> map = new TreeMap<>(); 117 map.entrySet().stream().sorted(Map.Entry.comparingByKey(String.CASE_INSENSITIVE_ORDER)); 118 } 119 120 public void testJDK8033590() { 121 Manager a = new Manager("John Doe", 1234, 16); 122 Manager b = new Manager("Jane Roe", 2468, 16); 123 Department da = new Department(a, "X"); 124 Department db = new Department(b, "X"); 125 126 Comparator<Department> cmp = Comparator.comparing(Department::getHR) 127 .thenComparing(Department::getManager, Employee.C); 128 assertTrue(cmp.compare(da, db) < 0); 129 130 cmp = Comparator.comparing(Department::getHR) 131 .thenComparing(Department::getManager, Manager.C); 132 assertTrue(cmp.compare(da, db) == 0); 133 134 cmp = Comparator.comparing(Department::getHR) 135 .thenComparing(Department::getManager, Person.C); 136 assertTrue(cmp.compare(da, db) > 0); 137 } 138} 139