Thinking in java -- set和存储顺序
来源:互联网 发布:java lambda this 编辑:程序博客网 时间:2024/06/15 20:52
先运行一下代码,
package containers;//: containers/TypesForSets.java// Methods necessary to put your own type in a Set.import java.util.*;class SetType { int i; public SetType(int n) { i = n; } public boolean equals(Object o) { return o instanceof SetType && (i == ((SetType) o).i); } public String toString() { return Integer.toString(i); }}class HashType extends SetType { public HashType(int n) { super(n); } public int hashCode() { return i; }}class TreeType extends SetType implements Comparable<TreeType> { public TreeType(int n) { super(n); } public int compareTo(TreeType arg) { return (arg.i < i ? -1 : (arg.i == i ? 0 : 1)); }}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 (Exception e) { throw new RuntimeException(e); } return set; } static <T> void test(Set<T> set, Class<T> type) { fill(set, type); fill(set, type); // Try to add duplicates fill(set, type); System.out.println(set); } public static void main(String[] args) { test(new HashSet<HashType>(), HashType.class); test(new LinkedHashSet<HashType>(), HashType.class); test(new TreeSet<TreeType>(), TreeType.class); // Things that don't work: test(new HashSet<SetType>(), SetType.class); test(new HashSet<TreeType>(), TreeType.class); test(new LinkedHashSet<SetType>(), SetType.class); test(new LinkedHashSet<TreeType>(), TreeType.class); try { test(new TreeSet<SetType>(), SetType.class); } catch (Exception e) { System.out.println(e.getMessage()); } try { test(new TreeSet<HashType>(), HashType.class); } catch (Exception e) { System.out.println(e.getMessage()); } }} /* * Output: (Sample) [2, 4, 9, 8, 6, 1, 3, 7, 5, 0] [0, 1, 2, 3, 4, 5, 6, 7, * 8, 9] [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] [9, 9, 7, 5, 1, 2, 6, 3, 0, 7, 2, 4, * 4, 7, 9, 1, 3, 6, 2, 4, 3, 0, 5, 0, 8, 8, 8, 6, 5, 1] [0, 5, 5, 6, 5, 0, * 3, 1, 9, 8, 4, 2, 3, 9, 7, 3, 4, 4, 0, 7, 1, 9, 6, 2, 1, 8, 2, 8, 6, 7] * [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] java.lang.ClassCastException: SetType * cannot be cast to java.lang.Comparable java.lang.ClassCastException: * HashType cannot be cast to java.lang.Comparable */// :~
上面这段代码讲解了HashSet,LinkedHashSet,TreeSet的存储。
定义了四个类
- SetType类重写了toString和equals方法。
- HashType类继承SetType,定义hashCode方法。
- TreeType类继承SetType,实现Comparable接口,实现compareTo方法
- TypesForSets测试类,代码中通过fill方法,对不确定类型的Set方法塞值。
运行输出结果:
[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]
[1, 2, 9, 4, 0, 0, 5, 2, 3, 0, 6, 8, 5, 8, 8, 3, 3, 6, 4, 7, 9, 4, 1, 6, 2, 1, 5, 7, 9, 7]
[3, 7, 1, 8, 0, 8, 6, 3, 7, 3, 0, 8, 4, 5, 9, 2, 7, 5, 2, 4, 4, 9, 6, 9, 1, 2, 0, 1, 6, 5]
[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]
java.lang.ClassCastException: containers.SetType cannot be cast to java.lang.Comparable
java.lang.ClassCastException: containers.HashType cannot be cast to java.lang.Comparable
分析结果:
第1、2test方法,是有序且不重复的存储。
第3个TreeType类实现compareTo方法,数据结构安装compareTo指定的规则进行排序
第4、5、6、7,都是没有去重的排序,理论上set容器应该是会去重的,原因是SetType与TreeType类均没有增加hashCode方法,详见这篇文章讲解重写hashcode的必要性:http://www.cnblogs.com/anrainie/archive/2012/04/27/2473196.html
第8、9,抛出了异常,
java.lang.ClassCastException: containers.SetType cannot be cast to java.lang.Comparable
java.lang.ClassCastException: containers.HashType cannot be cast to java.lang.Comparable
提示说没有找到java.lang.Comparable类,
总结,
- *Set,存储的对象类,类必须重写hashCode方法。
- *TreeSet,存储的对象类,类必须实现Comparable接口的compareTo方法。
参考,“Thinking in java 17.6章节”
- Thinking in java -- set和存储顺序
- Java - Set和存储顺序
- 数据存储 堆栈和堆 thinking in java
- Thinking in Java:对象初始化顺序
- Thinking in Java--对象存储位置
- Thinking in Java之Set接口、HashSet源码学习
- Thinking in Java之Set接口、HashSet源码学习
- 《Thinking in Java》和《Core Java》
- Thinking in java:对比C++和java
- 初始化顺序(Thinking in Java中的一段有意思的例子)
- Thinking in Java 构造器的调用顺序
- Thinking in Java之类内部变量定义先后顺序
- Thinking in Java之静态数据初始化顺序
- Thinking in java 读书笔记(四、toString,class的初始化顺序)
- 《Thinking in Java》笔记之调用构造器顺序
- 自动递增和递减 (thinking in java)
- Thinking in Java RTTI和反射机制
- Thinking in Java(5)-finalize()和初始化
- Openstack并行性能加速(转)
- HashMap源码阅读(2)- 碰撞(冲突)与扩容
- Codeforces Round #247 (Div. 2) C k-Tree
- Java中Math类的几个四舍五入方法的区别
- centos 安装软件
- Thinking in java -- set和存储顺序
- SQLite支持的数据类型
- 深入理解Java内存模型
- 【数据结构】链表
- RFID作业2-3
- Oracle创建自增字段方法-ORACLE SEQUENCE的简单介绍
- getch()和getchar()的区别
- OpenCV使用FileStorage保存Mat数据
- vim学习笔记(1)——vim操作