<? extends T> 与 <? super T>
<? extends T>
是Get First,适用于消费集合元素为主的场景;<? super T>
是Put First,适用于生产集合元素为主的场景
例如:Object > 动物 > 猫 > 咖啡猫
1 2 3
| List<Animal> animal = new ArrayList<>(); List<Cat> cat = new ArrayList<>(); List<Garfield> garfield = new ArrayList<>();
|
<? extends Cat> |
<? super Cat> |
赋值 |
×(只能赋值Cat或Cat的子类) |
√ |
animal |
√ |
√ |
cat |
√ |
×(只能赋值Cat或Cat的父类) |
garfiedl |
<? extends Cat> |
<? super Cat> |
add |
× |
×(只能添加Cat或Cat子类) |
animal |
× |
√ |
cat |
× |
√ |
garfiedl |
<? extends Cat> |
<? super Cat> |
get |
√(Cat 或 Object) |
√(泛型丢失,只能返回Object) |
|
元素的比较
Comparable 和 Comparator
Java 中两个对象比较的方法通常用在元素排序中,常用的两个接口分别是Comparable和Comparator,前者是自己和自己比,可以看做是自营性质的比较器;后者是第三方比较器,可以看做是平台性质的比较器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class SearchResult implements Comparable<SearchResult>{
int relativeRatio; long count; int recentOrders;
public SearchResult(int relativeRatio, long count) { this.relativeRatio = relativeRatio; this.count = count; }
@Override public int compareTo(SearchResult o) {
if (this.relativeRatio != o.relativeRatio) { return this.relativeRatio > o.relativeRatio ? 1 : -1; }
if (this.count != o.count) { return this.count > o.count ? 1 : -1; }
return 0; } }
|
当业务不符合要求时,根据开闭原则,最好不要修改已交付的类。使用Comparator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class SearchResultComparator implements Comparator<SearchResult> { @Override public int compare(SearchResult o1, SearchResult o2) { if (o1.relativeRatio != o2.relativeRatio) { return o1.relativeRatio > o2.relativeRatio ? 1 : -1; }
if (o1.recentOrders != o2.recentOrders) { return o1.recentOrders > o2.recentOrders ? 1 : -1; }
if (o1.count != o2.count) { return o1.count > o2.count ? 1 : -1; }
return 0; } }
|
hashCode 和 equals
- 如果两个对象的equals的结果是相等的,则两个对象的hasCode的返回结果必须相同的
- 任何时候覆写equals,都必须同时覆写hashCode
1 2
| if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))
|
当hashCode相等时,需要再调用一次值的比较;但是若hashCode不同,将直接判定Object不同,跳过equals, 加快处理效率