A:集合的由来
数组长度是固定,当添加的元素超过了数组的长度时需要对数组重新定义,太麻烦
java内部给我们提供了集合类,能存储任意对象,长度是可以改变的,随着元素的增加而增加,随着元素的减少而减少
B:数组和集合的区别
* 区别1 :
数组既可以存储基本数据类型,又可以存储引用数据类型,基本数据类型存储的是值,引用数据类型存储的是地址值
集合只能存储引用数据类型(对象)集合中也可以存储基本数据类型,但是在存储的时候会自动装箱变成对象
* 区别2:
数组长度是固定的,不能自动增长
集合的长度的是可变的,可以根据元素的增加而增长,1.5倍增长
C:数组和集合什么时候用
1,如果元素个数是固定的推荐用数组
2,如果元素个数不是固定的推荐用集合
单列集合的框架
Collection
-- list(有序,有索引,可重复)
ArrayList(数组)数组代表在内存分配了连续的内存空间,访问速速快
LinkedList(链表)链表,增删快,查询慢,线程不安全
Vector数组(java1.0)
-- Set(无序,不可重复)
HashSet(哈希表)
TreeSet(二叉树)
集合的遍历
其实就是依次获取集合中的每一个元素。
1创建集合对象,
2创建元素对象(如果是String就直接存入)
3将元素添加进集合,
4遍历了Object() toArray(),还有一种Iterator();迭代器
迭代器概述
集合是用来存储元素,存储的元素需要查看,那么就需要迭代(遍历)
Collection存储自定义对象并用迭代器遍历
迭代器原理
迭代器原理:迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,
所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法,
这样做是可以的,但是会让整个集合体系过于臃肿,迭代器是将这样的方法向上抽取出接口,
然后在每个类的内部,定义自己迭代方式,这样做的好处有二,
第一规定了整个集合体系的遍历方式都是hasNext()和next()方法,
第二,代码有底层内部实现,使用者不用管怎么实现的,会用即可
* boolean hasNext()是否有下一个
* boolean hasPrevious()是否有前一个
* Object next()返回下一个元素
* Object previous();返回上一个元素
Vector 的迭代只能用枚举迭代
* A:数组
* 查询快修改也快
* 增删慢
* B:链表
* 查询慢,修改也慢
* 增删快
A:List的三个子类的特点
ArrayList:
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。
Vector:
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
Vector相对ArrayList查询慢(线程安全的)
Vector相对LinkedList增删慢(数组结构)
LinkedList:
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。
Vector和ArrayList的区别
Vector是线程安全的,效率低
ArrayList是线程不安全的,效率高
共同点:都是数组实现的
ArrayList和LinkedList的区别
ArrayList底层是数组结果,查询和修改快
LinkedList底层是链表结构的,增和删比较快,查询和修改比较慢
共同点:都是线程不安全的
* B:List有三个儿子,我们到底使用谁呢?
查询多用ArrayList
增删多用LinkedList
如果都多ArrayList
栈:先进后出 1 2 3 4 , 4 3 2 1
队列:先进先出1 2 3 4, 1 2 3 4
泛型概述:
提高安全性(将运行期的错误转换到编译其)
省去强转的麻烦
泛型的使用:
<>中方的必须是数据类型
泛型使用注意事项:
前后泛型必须一致,或者后面的泛型可以省略不写(1.7版本新特性)菱形泛型
next方法只能调用一次,
泛型的由来:通过obje转型问题引入
早期的object类型可以接受任意类型的对象,但是在实际使用中,会有类型转换问题,也就存在了安全隐患
泛型类的概述:
把泛型定义在类上
泛型方法:
方法泛型要与类的泛型一致,如果不一致,需要在方法上声明泛型,静态方法必须声明自己的泛型
泛型通配符:
当右边不确定泛型类型的时候.可以吧左边泛型定义为<?>
增强for概述:
简化数组和collection集合的遍历
好处:简化遍历
增强for底层依赖的是迭代器Iterator
普通for可以删除元素
增强for不能删除元素,只能遍历
迭代器iterator不能删除元素,只能遍历
数组转集合:
数组转集合虽然不能增加或删除元素,但是可以用集合的思想操作数组,也就是说可以使用其他集合中的方法
基本数据类型的数组转换成集合会将整个数组当成一个对象
集合转换数组,数组的长度小于集合的长度,转换后数组的长度等于集合的size();
Set
HashSet
方法:与List集合中方法一样。
元素唯一:
在添加元素时,会对集合中已有的元素和你要添加的元素做比较,
如果集合中有相同的元素,就不添加,返回false。
判断依据:
在存储自定义对象是,他会根据自定义对象中的hashCode()方法和equals()方法进行判断,
两个对象是否是相同的元素。
添加一个元素,
先会判断添加的元素和集合中所有元素,hashCode 是否相等,
如果相等在来调用equals方法进行比较,如果结果为true不添加,结果为false添加这个元素
如果hashCode不相等,直接添加元素
注意:
如果想让集合中存储自定义对象去重,那么必须在自定义对象的这个类中重写hashCode和equals方法。
(开发时自动生成即可)
保证元素唯一:
重写hashCode和equals方法
LinkedHashSet 他是HashSet的子类
特点:保证元素唯一,存储有序。
TreeSet
自然排序接口 Comparable 重写方法 compareTo ,使用:存储的元素需要实现这个接口
TreeSet<Person> ts = new TreeSet<>();
如果这个集合存储的是Person对象,那就需要在Person这个类中实现Comparable接口,并重写compareTo方法
比较器接口 Comparator 重写方法 compare ,使用:创建集合对象,作为参数传进去
使用比较器时,这个Person类中可以不实现Comparable接口,但是在创建集合的时候需要传参数
参数就是Comparator的子类对象
*是否可以同时使用自然排序和比较器 ? 可以,优先使用比较器。
List 和 Set :
1.List
a.普通for循环, 使用get()逐个获取
b.调用iterator()方法得到Iterator, 使用hasNext()和next()方法
c.增强for循环, 只要可以使用Iterator的类都可以用
d.Vector集合可以使用Enumeration的hasMoreElements()和nextElement()方法
2.Set
a.调用iterator()方法得到Iterator, 使用hasNext()和next()方法
b.增强for循环, 只要可以使用Iterator的类都可以用
Set:
Collection
|--List
有序(存储顺序和取出顺序一致),可重复
|--Set
无序(存储顺序和取出顺序不一致)唯一
虽然set集合的元素无序,但是作为集合来说,它肯定有自己的存储顺序,而你的顺序恰好和他的存储顺序不一致,这代表不了有序,你可以多存储一些数据,就能看到效果
HashSet 它不保证set的迭代顺序;特别是他不保证该顺序恒久不变
HashSet 类概述:
不保证set的迭代顺序
特别是他不保证该顺序的恒久不变
HashSet 如何保证元素唯一性?
底层数据结构是哈希表(元素是链表的数组)
哈希表依赖于哈希值存储
添加功能底层依赖两个方法
int hashCode
boolean equals (Object obj)
HashSet:存储字符串并遍历
问题:为什么存储字符串的时候字符串内容一样却只存储了一个呢?
通过查看add方法的原码,我们知道这个方法底层依赖两个方法:hashCode()和equals()
步骤:
首先比较哈希值
如果相同就继续走,比较地址值或者走equals()
如果不同就添加到集合
按照方法的步骤来说:
先看hashcode()值是否相同
相同:继续走equals()方法
返回true:说明元素重复,就不添加
返回false:说明元素不重复,就添加到集合
不同:就直接把元素添加到集合
LinkedHashSet:底层数据结构由哈希表和链表组成
哈希表保证元素的唯一性
链表保证有元素就有数(存储和取出是一致)
TreeSet 概述:能够对元素按照某种规则进行排序
或者根据创建set是提供的comparator 进行排序
具体取决于使用的构造方法
TreeSet 是如何保证元素的排序和唯一性的?
底层数据结构是红黑数(红黑数是一种自平衡的二叉树)
排序的方式有两种:
A:自然排序Comparable
让元素所属的类实现自然排序接口Comparable
B:比较器排序CompareTo(集合具备可比较性)
让集合的构造方法接收一个比较器的子类对象Comparator
真正的比较是依赖于元素的CompareTo()方法,而这个方法是定义在Comparable里面的
所以,你要重写该方法,就必须先实现Comparable这个接口,这个接口就是自然排序
如果一个类的元素想要进行自然排序,必须要实现Comparable接口
如果一个方法的参数是接口,那么真正要的是接口的实现类的对象
而匿名内部类就可以实现这个东西
(接口) Map 集合:
特点:可以存储键值对的元素,将键映射到值得对象,一个映射不能包含重复的键,每个键最多只能映射一个值
Map 集合和 Collection 集合的区别?
Map 集合存储的元素是成对出现的,Map 集合的键是唯一的,值是可重复的,
Collection 集合存储的原始是单独痴线的,Collection 的儿子Set是唯一的,List 是可重复的
Map 接口的概述:
将键映射到值的对象
一个映射不能包含重复的键
每个键最多只能映射到一个值
Map 接口和 Collection 接口的不同
Map 是双列的,Collection 是单列的
Map 的键唯一,Collection 的子体系Set 是唯一的
Map 集合的数据结构针对键有效,跟值无关
Collection 集合的数据结构是针对元素有效
注意:
Map 集合的数据结构针对键有效.跟值无关
Collection 集合的数据结构是针对元素有效
Map 存储 键 值
HashMap
键唯一,保证键唯一需要重写键对应类的hashCode方法和equals方法。
LinkedHashMap
底层是链表实现的可以保证怎么存就怎么取
TreeMap
键唯一,根据其键的自然顺序进行排序(键对应的类实现自然排序接口 Comparable 接口),
或者根据集合时的 Comparator 进行排序(比较器)。
遍历 Map 集合
/**
遍历map集合方式一:
思路:
获取所有的键
遍历键的集合
根据键去找对应的值
遍历map集合方式二:
思路:
获取所有键值对对象的集合
遍历键值对对象的集合,得到每一个键值对对象
根据键值对对象得到每一个键值对
*/
HashMap和Hashtable的区别
Hashtable是JDK1.0版本出现的,是线程安全的,效率低,
HashMap是JDK1.2版本出现的,是线程不安全的,效率高
Hashtable不可以存储null键和null值,
HashMap可以存储null键和null值
HashMap:是基于哈希表的Map接口实现
哈希表的作用是用来保证键的唯一性
LinkedHashMap Map 接口的哈希表和连接列表实现基友可 以预知的迭代顺序
TreeMap 类概述:
键是红黑树结构,可以保证键的排序和唯一性
Hashtable 和 HashMap 的区别:
Hashtable:线程安全,效率低,不允许null键和null值
HashMap:线程不安全,效率高,允许null键和null值
共同点:都是哈希算法,都是双列集合
List Set Map 等接口是否都继承自 Map 接口:
List Set 不是继承自 Map 接口,他们都继承自 Collection 接口
Map 接口本身就是顶层接口
Collections:是针对集合操作的工具类,都是静态方法
Collection 和 Collections 的区别
Collection:是单列集合的顶层接口,有子接口List和Set
Collections:是针对集合操作的工具类,有对集合进行排序 和二分查找的方法
|
|