数组和集合的区别:
数组: 存储多个数据
相同数据类型的有序集合
特点:
1.引用数据类型,对象数据
2.定长的,长度一旦确定不可改变
3.有序的,从0开始,每次+1
4.数据类型要求相同集合:
存储任意类型的数据(引用数据类型)
根据数据的增删长度自动改变
Collection接口
构成Collection的单位是元素。Collection接口通常不能直接使用,但是该接口提供了添加元素,删除元素,管理数据的方法。由于List接口与Set接口都继承了Collection接口,因此这些方法对List集合和Set集合是通用的。
List集合
List集合包括List接口以及List接口的所以实现类。List接口的所有实现类。
List集合的特点:
List集合中的元素允许重复(可重复),各元素就是对象插入的顺序(有序),类似Java可以通过索引来访问集合中的元素(有索引)。
List接口继承了Collection接口,因此包含Collection中的所有方法,此外,List接口还定义了两个重要的方法。
get()方法和set()方法。
List接口的实现类:主要常用的是:ArrayList,LinkedList,Vector。
遍历方式: 1)for 2)foreach 3)iterator 4)listIterator
ArrayList : 有序(添加的顺序与内部存储数据的顺序一致),有索引 可重复
List接口的可调整大小的阵列实现。 实现所有可选列表操作,并允许所有元素,包括null 。
底层结构: 数组|可变数组
特点: 查询效率高 增删效率低
应用场景: 适合应用在大量查询,少量增删的位置
扩容机制: 初始容量默认为10 DEFAULT_CAPACITY = 10,每次扩容原容量的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
新增功能: 无新增方法
Vector : 向量
与ArrayList类似
1) 扩容 : Vector每次扩容原容量的2倍 ,ArrayList 每次扩容原容量的1.5倍
2) 同步问题 : Vector线程安全的|同步的, ArrayList线程不安全|不同步LinkedList : 有序 可重复
双链表,并允许所有元素(包括null )。
底层结构: 双向链表结构
数据以节点为单位,记录上下节点的地址
特点: 查询效率较低,增删效率高
应用场景: 大量做增删,少量做查询的地方
新增功能: 根据链表头尾进行操作的方法注意:
定义List存储自定义引用数据类型数据的时候,javabean中应该重写equals与toString
javabean规范:
1)类是公共的
2)至少提供一个空构造
3)属性私有化
4)公共的访问方式
5)重写toString与equals
6)根据需要实现序列化接口
Set集合
特点:无序(添加的顺序与内部真实存储数据的顺序不一致),不可重复,没有索引
Set接口的实现类:主要常用的是:TreeSet,HashSet。
遍历方式: 1) foreach 2)iterator
TreeSet : 无序,不可重复
底层结构: 红黑树(平衡二叉树)
特点: 数据默认升序排序
应用场景: 存储多个数据中不允许重复数据,并且想要排序就可以选中使用TreeSet
新增方法: 新增了一些与比较相关的方法注意: 不同类型的数据不能使用TreeSet实现排序
自定义引用数据类型如何实现默认升序排序?
定义User类型,存储多个用户对象放入TreeSet集合,是否能够成功实现排序,是否能够实现去重
自定义引用数据类型对象存储: 要求定义比较规则
自定义引用数据类型的去重: 根据比较规则的返回值做去重,返回值为0代表相同,去重
自定义引用数据类型的排序: 根据比较规则的做排序,默认升序排序,可以根据比较规则方法的实现,实现一个降序排序比较规则:
内部比较器|自然排序 : 比较规则定义在类的内部
自定义引用数据类型实现Comparable<T>接口,重写compareTo方法,方法的内部制定当前类型数据的比较规则
根据compareTo返回值决定去重与排序
o1.compareTo(o2)
0 --> o1=o2
负数 --> o1<o2
正数 --> o1>o2外部比较器|定制排序 : 比较规则定义在类的外部(一般使用匿名内部类实现外部比较器)
定义一个实现类,实现Comparator接口,重写compare方法,在方法内部制定比较规则总结:
定义TreeSet集合的时候,构造器的参数是否指定使用哪一种外部比较规则,如果没有指定外部比较规则,默认找到数据的内部比较规则
如果外部与内部比较规则都不存在,排除类型转换异常
匿名内部类用来简化没有自己作用的,使用次数比较少的,接口实现类
HashSet : 无序 不可重复
底层: 是由HashMap维护的
底层: 哈希表(数组+链表+红黑树)
特点: 查询,增删效率高
无序,去重
新增功能: 无新增方法
自定义引用数据类型数据的去重: 两个对象所有成员变量的值都想等,应该去重
javabean类中重写hashCode与equals方法,实现根据所有成员变量的值进行计算,而非默认的地址hashCode与equals之间的关系:
两个对象,调用hashCode相等,equals就一定相等??? --> 不对
hashCode相等,证明数据存储在同一个位桶中,但是equals不一定相等,所有多个数据之间才使用链存储
两个对象,调用equals相等,hashCode就一定相等??? --> 对
equals相等就是相同的对象,必须存储在同一个桶中,否则无法实现去重,所以要求必须根据成员变量的值重写hashCode的实现
hashCode存在可以提高哈希表结构存储数据的效率,减少数据之间调用equals比较的次数,提高效率
可变参数: ...
1.参数的个数可以为0~n个,但是可变参数的类型要保持一致
2.可变参数必须存在与参数列表的最后位置
3.为可变参数构建一个数组,使用可变的参数的时候要使用数组的操作方式
Map详解:
Map用于保存具有映射关系的数据,Map里保存着两组数据:key和value,它们都可以使任何引用类型的数据,但key不能重复。所以通过指定的key就可以取出对应的value。
Map的遍历方式:
1) keySet() 获取所有的key,得到一个Set集合
2) values() 获取所有的value
3) entrySet() 获取所有的键值对->entry->Set
HashMap :
底层结构: 哈希表(数组+链表+红黑树)
基于哈希表的Map接口的实现。并允许null值和null键。
新增功能: 无新增功能初始容量Capacity: DEFAULT_INITIAL_CAPACITY = 1<<4 = 16 哈希表结构中的数组的默认初始长度
加载因子: loadFactor = DEFAULT_LOAD_FACTOR = 0.75f;
容量size : 集合中存储数据的个数
扩容临界值(阀值)threshold : size>Capacity*loadFactor -->resize()
扩容机制: 内部的数组为原容量的2倍HashMap存储机制:
数组的长度: 2的整数次幂
1.根据key调用hash方法,计算出了key的hash值 int hash = (h = key.hashCode()) ^ (h >>> 16)
2.根据hash值计算位桶的索引 : index = (n - 1) & hash 优化的算法: 帮助提高效率,尽量减少哈希碰撞,散列的分布在每一个位桶中,提高效率
3.判断数组table中对应索引位置table[index]==null,内部没有节点,当前要存储的键值对数据直接创建成为新节点new Node(hash, key, value, null)->放入数组index位桶中,作为链表头节点存在
4.不等于null,从链表头开始遍历这个链表,判断每一个节点的key是否与要存储的键值对的key相等,如果相等value覆盖,都不相等,创建新节点,加入原链表的最后
5.size++; if (++size > threshold) resize(); 判断如果>扩容临界值,进行扩容在HashMap中,存储,value覆盖,去重等过程都是根据key计算的,只有在创建新节点|覆盖value值的时候,才与value有关系
定义一个HashMap存储键值对数据,key为学教师型Teacher类型,value为教师锁教授的学科,实现HashMap的去重原则(根据key做去重,value)
key的类型需要重写hashCode与equals方法,因为HashMap的哈希表是根据key存储数据,根据key做去重HashMap与Hashtable之间区别:
1.继承体系不同
2.null值要求不同
HashMap->允许null值和null键
Hashtable->键值对都不能为null
3.同步问题
HashMap: 线程不安全|不同步哈希表
Hashtable: 线程安全|同步的哈希表
内部方法上通过synchronized同步锁控制线程安全
4.初始容量,扩容机制不同
HashMap:
初始容量 : 16
扩容机制: 2倍
Hashtable:
初始容量 : 11
扩容机制: 2倍+1 int newCapacity = (oldCapacity << 1) + 1;
5.hash实现不同(求位桶的索引的方式不同)
HashMap: int hash = (h = key.hashCode()) ^ (h >>> 16)
Hashtable: int hash = key.hashCode();
TreeMap :
底层结构: 红黑树
特点: 默认升序排序(key)
实现: 根据key做存储,根据做去重,根据key做排序
TreeSet底层是由TreeMap维护的
新增功能: 新增了一些与比较相关的方法
去重: key的类型要求实现内部比较规则或者TreeMap对象构造器中指定外部比较规则
优先找外部,没有外部找内部
排序去重 : 都是根据比较器实现,与equals,hashCode没有关系
如何解决HashMap线程不安全?
1.使用Hashtable
2.使用Collections类的synchronizedMap(Map<K,V> m)
3.juc高级并发编程包下的 ConcurrentHashMap 线程安全的哈希表 --> 推荐
集合工具类
Collections 操作集合工具类 (Map集合无工具类)
void sort(List) //对List容器内的元素排序,排序的规则是按照升序进行排序。
void shuffle(List) //对List容器内的元素进行随机排列
void reverse(List) //对List容器内的元素进行逆续排列
void fill(List, Object) //用一个特定的对象重写整个List容器
int binarySearch(List, Object)//对于顺序的List容器,采用折半查找的方法查找特定对象