Java Generics And Collections笔记(Part II)
2018-02-22 18:30 秋风将涌起的某夜 阅读(127) 评论(0) 收藏 举报3. Comparison and Bounds
3.1 Comparable
interface Comparable<T> {
public int compareTo(T o);
}
The compareTo method returns a value that is negative, zero, or positive depending upon whether the argument is less than, equal to, or greater than the given object.
Comparable的几条性质:
-
anti-symmetric
sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
-
transitive
if x.compareTo(y) < 0 and y.compareTo(z) < 0 then x.compareTo(z) < 0
-
congruence
if x.compareTo(y) == 0 then sgn(x.compareTo(z)) == sgn(y.compareTo(z))
3.2 Maximum of a Collection
如果该集合的元素实现了Comparable,(Object &是为了和legacy code兼容,不然返回值的类型变成了Comparable类型):
public static <T extends Object & Comparable<? super T>> T maxOf(Collection<? extends T> coll) {
Iterator<T> it = coll.iterator();
T candidate = it.next();
while (it.hasNext()) {
T tmp = it.next();
if (candidate.compareTo(tmp) < 0) {
candidate = tmp;
}
}
return candidate;
}
3.4 Comparator
interface Comparator<T> {
public int compare(T o1, T o2);
public boolean equals(Object obj);
}
The compare method returns a value that is negative, zero, or positive depending upon whether the first object is less than, equal to, or greater than the second object—just as with compareTo.
public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) {
Iterator<? extends T> i = coll.iterator();
T candidate = i.next();
while (i.hasNext()) {
T next = i.next();
if (comp.compare(next, candidate) > 0)
candidate = next;
}
return candidate;
}
3.5 Enumerated Types
枚举类型都是以下声明的子类
public abstract class Enum<E extends Enum<E>> implements Comparable<E>
对于枚举
enum Season { WINTER, SPRING, SUMMER, FALL }
可以理解为
final class Season extends Enum<Season>
Enum<Season> implements Comparable<Season>
从而,我们可以比较Season类型的值,但是无法比较Season类型和其他类型的值。
如果没有类型变量,枚举类型的声明变成了
public abstract class Enum implements Comparable<Enum>
枚举类型Season的声明就变成了
class Season extends Enum implements Comparable<Enum>
这样,任何两个枚举类型都可以互相比较,自然不是我们所需要的。
4. Declarations
4.1 Constructors
class Pair<T, U> {
private final T first;
private final U second;
public Pair(T first, U second) {
this.first = first;
this.second = second;
}
public T getFirst() {
return first;
}
public U getSecond() {
return second
}
}
// 调用构造函数别忘记了类型参数
Pair<String, Integer> pair = new Pair<String, Integer>("two", 2);
4.2 Static Members
静态成员返回值不要带有类型参数。
One consequence is that static members of a generic class are shared across all instantiations of that class, including instantiations at different types. Static members of a class cannot refer to the type parameter of a generic class, and when accessing a static member the class name should not be parameterized.
4.3 Nested Classes
Java permits nesting one class inside another. If the outer class has type parameters and the inner class is not static, then type parameters of the outer class are visible within the inner class.
When the nested Node class is static, the type parameter E is not in scope for this class.
If the node classes had been made public rather than private, you would refer to the node class in the first example as LinkedCollection
.Node, whereas you would refer to the node class in the second example as LinkedCollection.Node .
4.4 How Erasure Works
类型擦除定义如下:
drop all type parameters from parameterized types, and replace any type variable with the erasure of its bound, or with Object if it has no bound, or with the erasure of the leftmost bound if it has multiple bounds.
举例如下:
- List<Integer>, List<String>, List<List<String>>类型擦除后是List
- List<Integer>[]类型擦除后是List[]
- raw type类型擦除后还是本身,如List
- primitive type类型擦除后还是本身,如int
- 无类型参数的类型经过类型擦除后还是本身,如Integer
- 类型参数有界限(bound),比如Comparable<? super T>,类型擦除后是Comparable,无界限(bound),类型擦除后是Object
- T extends Object & Comparable<? super T> 类型擦除后是Object,取左边的界限(bound)
- 嵌套类LinkedCollection<E>.Node或者静态内部类LinkedCollection.Node<E> 类型擦除后是LinkedCollection.Node.
涉及到重载,函数签名在类型擦除后不能一致(返回值也算函数签名的一部分!),一个类不能同时实现两个类型擦除后一致的接口。
浙公网安备 33010602011771号