JAVA_JCF(Java Collection Framework)学习笔记(三)
2016-02-02 14:38
537 查看
Set接口
Collection|-------List:元素是有序的,元素可以重复,因为该集合体系有索引。
|------ArrayList:底层的数组结构使用的是数组结构。特点:查询速度快,但是增删稍慢,线程不同步。
|------LinkedList:底层使用的链表结构。特点:增删速度快,查询慢。
|------Vector:底层是数组结构,线程同步,被ArrayList替代了。
|-------Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。
|-------HashSet:底层数据结构是哈希表.线程是非同步的
保证元素唯一性的原理,判断元素的hashCode值是否相同
如果相同还会继续判断元素的equals方法,是否为true
|-------TreeSet:可以对Set集合中的元素进行排序
底层数据结构是二叉树
保证元素唯一性的依据:compareTo方法return 0
HashSet
底层数据结构使用哈希表HashSet是如何保证元素唯一性的呢?
是通过元素的两个方法,hashCode和equals方法。
如果元素的hashCode值相同,才会判断equals是否为true。
如果元素的hashCode值不同,不会调用equals。
Person类:
public class Person { private String name; private String age; public Person() { } public Person(String name, String age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public boolean equals(Object obj) { System.out.println(this.name + "...equals"); if (!(obj instanceof Person)) { return false; } Person person = (Person) obj; return this.name.equals(person.getName()); } @Override public int hashCode() { System.out.println(this.name + "...hash"); return this.name.hashCode(); } }重写Person的hashCode方法和equals方法,观察使用HashSet添加person对象调用hashCode方法和equals方法。
@Test public void testHashSet1() { HashSet<Person> persons = new HashSet<Person>(); persons.add(new Person("lisi", "23")); persons.add(new Person("zhangsan", "24")); persons.add(new Person("wangwu", "25")); //===============输出结果===============// // lisi...hash // zhangsan...hash // wangwu...hash }只调用hashCode方法
@Test public void testHashSet1() { HashSet<Person> persons = new HashSet<Person>(); persons.add(new Person("lisi", "23")); persons.add(new Person("wangwu", "25")); persons.add(new Person("zhangsan", "24")); persons.add(new Person("wangwu", "26")); //===============输出结果===============// // lisi...hash // wangwu...hash // zhangsan...hash // wangwu...hash // wangwu...equals }当第四次添加name为wangwu的person对象时,由于hashset容器中已经存在name为wangwu的person对象,所以会继续调用person对象的equals方法。
注意:对于HashSet容器中判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。因为需要使用hash值在Hash表中查找元素,如果查出不仅仅是一个元素,则继续调用元素的equals方法,进行判断是否是同一个元素。
TreeSet
TreeSet排序的第一种方式,让元素自身具备比较性。元素类需要实现Comparable接口,覆盖compareTo方法,这种方式也成为了元素的自然排序,或者叫做默认排序。
TreeSet排序的第二种方式,当元素自身不具备比较性时,或者具备的比较性不是所需要的,这是需要让集合自身具备比较性,即集合初始化就有了比较性。
第一种排序方式:
Person类:
public class Person implements Comparable<Person> { private String name; private String age; public Person() { } public Person(String name, String age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public int compareTo(Person o) { int num = this.name.compareTo(o.name); if (num == 0) { num = new Integer(this.age).compareTo(new Integer(o.age)); } return num; } @Override public String toString() { return this.name + "..." + this.age; } }测试代码:
@Test public void testTreeSet() { TreeSet<Person> set = new TreeSet<Person>(); set.add(new Person("java001", "05")); set.add(new Person("java023", "08")); set.add(new Person("java003", "04")); set.add(new Person("java034", "03")); set.add(new Person("java034", "09")); Iterator<Person> iterator = set.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } }第二种排序:
package cn.wangyu.collection;测试类:
public class Person implements Comparable<Person> { private String name; private String age; public Person() { } public Person(String name, String age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public int compareTo(Person o) { int num = this.name.compareTo(o.name); if (num == 0) { num = new Integer(this.age).compareTo(new Integer(o.age)); } return num; } @Override public String toString() { return this.name + "..." + this.age; } }
@Test public void testTreeSet() { TreeSet<Person> set = new TreeSet<Person>(new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { int num = new Integer(o1.getName().length()).compareTo(new Integer(o2.getName().length())); if (num==0) { num = o1.getName().compareTo(o2.getName()); } return num; } }); set.add(new Person("java000001", "05")); set.add(new Person("java0023", "08")); set.add(new Person("ja3", "04")); set.add(new Person("ja034", "03")); set.add(new Person("java034", "09")); Iterator<Person> iterator = set.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } }当元素自身不具备比较性,或者具备的比较性不是所需要的。这是需要让容器具备比较性。
定义了比较器,将比较对象作为参数传递给TreeSet集合的构造函数
当两种排序都存在的情况下,以比较器为主,定义一个类,实现Comparator接口,覆盖compare方法。
相关文章推荐
- 经典排序算法(Java实现)
- 读书笔记-->Java内存分配策略初识
- myeclipse中java文件头注释格式设置
- windows下用Eclipse编译运行android原生浏览器
- 谈谈visual studio QTCreator eclipse的远程调试
- eclipse中maven插件安装及常用命令
- 简单Spring中的Quartz配置(收集)
- Mac OS下安装MyEclipse报错:Your system does not have sufficient memory to support MyEclipse
- R.java was modified manually! Reverting to generated version!(R文件丢失异常原因汇总)
- SpringMVC入门了解
- Caused by: java.lang.ClassNotFoundException: org.hibernate.engine.transaction.spi.TransactionContext
- java Remote Debug(远程调试)
- SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
- Spring通过构造方法注入的四种方式
- java web 过滤器跟拦截器的区别和使用
- java.lang.string
- Spring事务管理只对出现运行期异常进行回滚
- 0007-eclipse+OpenExplore
- Java class文件分析工具 -- Classpy
- java 常见异常总结