接口 | 描述 |
---|---|
Set | 存入Set的每一个元素都必须是唯一的,因为Set不保存重复元素.加入Set的元素必须定义equals()方法以确保对象的唯一性. Set和Collection有完全一样的接口.Set接口不保证维护元素的次序. |
HashSet * | 为快速查找而设计的Set.存入HashSet的元素必须定义HashCode()方法. |
TreeSet | 保持次序的Set,底层为树结构.使用它可以从Set中提取有序的序列.元素必须实现Comparable接口 |
LinkedHashSet | 具有HashSet的查询速度,且内部使用链表维护元素的顺序.于是在使用迭代器遍历Set时,结果会按元素插入的次序显示.元素也必须定义hashCode()方法. |
Example:
public class TypesForSets {
static <T> Set<T> fill(Set<T> set, Class<T> type) {
try {
for (int i = 0; i < 10; i++) {
set.add(type.getConstructor(int.class).newInstance(i));
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return set;
}
static <T> void test(Set<T> set, Class<T> type) {
fill(set, type);
fill(set, type);
fill(set, type);
fill(set, type);
System.out.println(set);
}
public static void main(String[] args) {
test(new HashSet<HashType>(), HashType.class);
test(new LinkedHashSet<>(), HashType.class);
test(new TreeSet<TreeType>(), TreeType.class);
test(new HashSet<SetType>(), SetType.class);
test(new HashSet<TreeType>(), TreeType.class);
test(new LinkedHashSet<SetType>(), SetType.class);
test(new LinkedHashSet<TreeType>(), TreeType.class);
test(new TreeSet<SetType>(), SetType.class);
test(new TreeSet<HashType>(), HashType.class);
}
}
class SetType {
int i;
public SetType(int n) {
i = n;
}
@Override
public boolean equals(Object o) {
return o instanceof SetType && (i == ((SetType) o).i);
}
@Override
public String toString() {
return Integer.toString(i);
}
}
class HashType extends SetType {
@Override
public int hashCode() {
return i;
}
public HashType(int n) {
super(n);
}
}
class TreeType extends SetType implements Comparable<TreeType> {
public TreeType(int n) {
super(n);
}
@Override
public int compareTo(TreeType o) {
return (o.i < i ? -1 : (o.i == i ? 0 : 1));
}
}
Result:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
[7, 7, 0, 2, 8, 5, 9, 1, 7, 4, 1, 1, 3, 2, 3, 1, 9, 9, 2, 8, 4, 6, 0, 8, 5, 4, 6, 8, 6, 3, 0, 3, 7, 5, 4, 0, 6, 5, 2, 9]
[8, 2, 6, 1, 5, 5, 4, 0, 0, 7, 1, 9, 6, 9, 3, 4, 8, 4, 7, 0, 4, 8, 3, 9, 3, 8, 7, 1, 7, 5, 5, 6, 1, 6, 2, 2, 0, 3, 2, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Exception in thread "main" java.lang.ClassCastException: 容器的深入研究_17.Set和存储顺序_17_6.SetType cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1290)
at java.util.TreeMap.put(TreeMap.java:538)
at java.util.TreeSet.add(TreeSet.java:255)
at 容器的深入研究_17.Set和存储顺序_17_6.TypesForSets.fill(TypesForSets.java:17)
at 容器的深入研究_17.Set和存储顺序_17_6.TypesForSets.test(TypesForSets.java:33)
at 容器的深入研究_17.Set和存储顺序_17_6.TypesForSets.main(TypesForSets.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)