Java--容器(Collection)(一)
2016-03-04 09:31
656 查看
容器这篇,我主要从理论理解角度写的,代码可能偏少,因为集合里的方法太多 了但是这些点都是写代码时应当注意的点。
学完了面向对象部分,上述图的层次结构应该不生疏了,这里简单的做些说明。
Collection函数库与数组的区别:
1). 数组的容量有限,而Collection库的容量而自己调整;
2). Collection函数库只能用来存放对象,而数组没有这样的限制
Collection库是java中的集合框架,collection接口是这个集合框架中的根接口,Colletction代表一组对象.接口是一种规范.Collection接口是一组允许重复的没有顺序的对象;Collection接口下的set接口(不允许重复,无指定顺序,若重复则会覆盖)和list接口(允许重复,有序);Map接口是一组成对的键-值对象(key-value)不能有重复的key,但可有重复value,通过一个对象找另外一个对象.
List接口里允许重复和有序
查看源码时我们会发现LinkedList里居然还有索引index,这是因为LinkedList类继承了Collection类
2. Set
Set接口里不允许重复,无指定顺序,若重复则会覆盖
- set接口虽然是Collection的子接口,但是其没有提供额外的方法, 猜想: hashSet类是数组+链表,TreeSet类是树
- TreeSet实现的Set接口,故数据元素不可重复(这里去除重复的方式是比较元素是否等于0,故这里无需重写hashCode和equals方法),另外TreeSet的元素是排序的。(对比:HashSet的元素必须重写hashCode和equals方法)
TreeSet确保元素实体可以排序,排序的比较器是public Treeset(Comparator<? super E>comparator)
3 . Map
(1). 底层实现是:数组+链表(例如LinkedList[] arr = new LinkedList[9]);
(2). Java中没有指针,但是可以通过个对象(即创建的节点)的属性来保存相关连接关系,其中key和value都可以是任何引用类型的数据;
(3). hashCode()是根据每个对象的地址生成的一个哈希码,每个对象的地址唯一,所以这个哈希码也唯一;
(4). 对于hashCode()与equals()配套重写的原因说明:java中规定两个对象的内容相同时(即euqals()为true时)其hashCode一定也得相同,所以hashCode和equals方法是得同时重写的;
(5). 重头戏:其子类HashMap和HashTable
常用方法的注意点:
A. put(成对存放)和putAll();
B. get():get()方法是通过equals来进行对象比较的,返回的是Object,转型时必须转型为相应的值的对象类型;
C. remove();
D. containKey(是否包含key),containValue(是否包含value)
HashTable和HashMap的区别
-1. 线程安全性:HashTable中的方法是同步的,而HashMap中的方法在缺省的情况下是非同步的,即HashTable较HashMap是线程安全的。在多线程并发的情况下,HashTable可以直接使用,而HashMap需要自己增加同步处理,即HashMap是Hashtable的轻量级实现。
-2. 继承不同:public class Hashtable extends Dictionary implements Map;
public class HashMap extends AbstractMap implements Map
-3. key-value的null值问题:Hashtable中,key和value都不允许出现null值;而在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即既可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。
-4. 遍历方式不同:Hashtable使用了 Iterator;HashMap也使用了Iterator,而由于历史原因,Hashtable还使用了Enumeration的方式 。
-5. 哈希值的使用不同:HashTable直接使用对象的hashCode。而HashMap重新计算hash值。
-6. 扩容方式不同:Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。
(6). TreeMap:与Set一样,Map中也有排序的类TreeMap
确保Key可以排序
提供key比较器:public TreeMap(Comparator
一、层次结构
学完了面向对象部分,上述图的层次结构应该不生疏了,这里简单的做些说明。
Collection函数库与数组的区别:
1). 数组的容量有限,而Collection库的容量而自己调整;
2). Collection函数库只能用来存放对象,而数组没有这样的限制
Collection库是java中的集合框架,collection接口是这个集合框架中的根接口,Colletction代表一组对象.接口是一种规范.Collection接口是一组允许重复的没有顺序的对象;Collection接口下的set接口(不允许重复,无指定顺序,若重复则会覆盖)和list接口(允许重复,有序);Map接口是一组成对的键-值对象(key-value)不能有重复的key,但可有重复value,通过一个对象找另外一个对象.
二、分别介绍
1 . List的三个实现类List接口里允许重复和有序
查看源码时我们会发现LinkedList里居然还有索引index,这是因为LinkedList类继承了Collection类
2. Set
Set接口里不允许重复,无指定顺序,若重复则会覆盖
- set接口虽然是Collection的子接口,但是其没有提供额外的方法, 猜想: hashSet类是数组+链表,TreeSet类是树
- TreeSet实现的Set接口,故数据元素不可重复(这里去除重复的方式是比较元素是否等于0,故这里无需重写hashCode和equals方法),另外TreeSet的元素是排序的。(对比:HashSet的元素必须重写hashCode和equals方法)
public class Person { private String name;// 名称 private int age;// 年龄 public Person() { super(); // TODO Auto-generated constructor stub } public Person(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "姓名:" + name + ", 年龄:" + age + "\n"; } } public class TestTreeSet { public static void main(String[] args) { Person p1 = new Person("张三", 33); Person p2 = new Person("李四", 22); Person p3 = new Person("王五", 44); Person p4 = new Person("赵六", 66); // 依次存放到TreeSet容器中,使用排序业务类 TreeSet<Person> persons = new TreeSet<Person>( new Comparator<Person>(){ @Override public int compare(Person o1, Person o2) { return o1.getAge() - o2.getAge(); } }); persons.add(p1); // TreeSet在添加数据的时候一边添加一边排序 // 而Collections.sort方式是在数据添加完后再排序 persons.add(p2); persons.add(p3); persons.add(p4); System.out.println(persons); // TreeSet数据的更改不会影响排序,因为数据是一边添加一边排序的 p4.setAge(0); System.out.println(persons); // TreeSet数据的更改不会影响排序,导致更改可能出现数据的重复,而此时已经无法检测了。 // 因此建议使用TreeSet时不要随意修改数据,此时可以使用final关键字来避免失误 p3.setName("张三"); p3.setAge(33); } } public class Person { private final String name;// 名称 private final int age;// 年龄 public Person() { super(); name = null;// 添加了final关键字必须初始化一个值 age = 0; } public Person(String name, int age) { super(); this.name = name; this.age = age; } // 添加了final关键字,无法提供set方法来修改数据 public String getName() { return name; } public int getAge() { return age; } }
TreeSet确保元素实体可以排序,排序的比较器是public Treeset(Comparator<? super E>comparator)
3 . Map
(1). 底层实现是:数组+链表(例如LinkedList[] arr = new LinkedList[9]);
(2). Java中没有指针,但是可以通过个对象(即创建的节点)的属性来保存相关连接关系,其中key和value都可以是任何引用类型的数据;
(3). hashCode()是根据每个对象的地址生成的一个哈希码,每个对象的地址唯一,所以这个哈希码也唯一;
(4). 对于hashCode()与equals()配套重写的原因说明:java中规定两个对象的内容相同时(即euqals()为true时)其hashCode一定也得相同,所以hashCode和equals方法是得同时重写的;
(5). 重头戏:其子类HashMap和HashTable
常用方法的注意点:
A. put(成对存放)和putAll();
B. get():get()方法是通过equals来进行对象比较的,返回的是Object,转型时必须转型为相应的值的对象类型;
C. remove();
D. containKey(是否包含key),containValue(是否包含value)
HashTable和HashMap的区别
-1. 线程安全性:HashTable中的方法是同步的,而HashMap中的方法在缺省的情况下是非同步的,即HashTable较HashMap是线程安全的。在多线程并发的情况下,HashTable可以直接使用,而HashMap需要自己增加同步处理,即HashMap是Hashtable的轻量级实现。
-2. 继承不同:public class Hashtable extends Dictionary implements Map;
public class HashMap extends AbstractMap implements Map
-3. key-value的null值问题:Hashtable中,key和value都不允许出现null值;而在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即既可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。
-4. 遍历方式不同:Hashtable使用了 Iterator;HashMap也使用了Iterator,而由于历史原因,Hashtable还使用了Enumeration的方式 。
-5. 哈希值的使用不同:HashTable直接使用对象的hashCode。而HashMap重新计算hash值。
-6. 扩容方式不同:Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。
(6). TreeMap:与Set一样,Map中也有排序的类TreeMap
确保Key可以排序
提供key比较器:public TreeMap(Comparator
相关文章推荐
- Leetcode:198. House Robber(JAVA)
- JAVA SDutOJ 题目收录
- eclipse 出包 is not a sibling in the same 问题修复
- Java 服务器端修改apk并重新打包签名
- Android studio导入eclipse的项目时,l解决libpng warning: iCCP: Not recognizing known sRGB profile that has be
- Java 学习的几个基础实验(Learn by doing)
- java读取文件的两种方法:java.io和java.lang.ClassLoader
- Java基础学习总结(50)——Java事务处理总结
- Java基础学习总结(50)——Java事务处理总结
- Java基础学习总结(50)——Java事务处理总结
- java中有没有指针
- 构建 struts2 spring3 mybatis 的maven项目 构建 pom.xml
- 在Eclipse中使用JUnit4进行单元测试(初级篇)
- Thrift入门及Java实例(一)
- 初探JVM之java内存区域
- Eclipse中输入系统变量和运行参数
- Java的Spring框架中DAO数据访问对象的使用示例
- java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting ‘name pattern’
- SpringMVC详细示例实战教程
- java中如何打印当前根目录