一:集合框架的概述
集合、数组都是对多个数据进行存储操作的结构,简称java容器。
数组在存储多个数据方面的特点:一旦初始化以后,其长度以及元素的类型也就确定了。
所以在存储多个数据方面的缺点:长度不可修改;数组中提供的方法非常有限,对于添加、删除、插入数据等操作,非常不便,效率不高;获取数组中实际的元素的个数的需求,数组没有现成的属性或方法可用。
二:集合框架
2.1、Collection接口:单列集合,用来存储一个一个的对象。
/**
* @Author: 随心的小新
* @Date: 2019/8/20 9:41
* Collection接口中声明的方法的测试
* 结论:向Collection接口的实现类的对象中添加数据object时,要求object所在类需要重写equals()方法。
*/
public class CollectionTest {
public void test1(){
Collection coll = new ArrayList ( );
coll.add(123);
coll.add ( new Person("tom",20) );
coll.add ( new java.lang.String ( "jenny" ) );
// hashCode ():返回当前对象的哈希值
System.out.println (coll.hashCode ());
// 集合----》数组:toArray();
Object[] arr = coll.toArray ();
for (int i = 0; i < arr.length; i++) {
System.out.println (arr[i]);
}
// 数组---》集合,调用Arrays.asList的静态方法
List<String> strings = Arrays.asList ( new String[]{"aa", "bb"} );
System.out.println (strings);
List strings1 = Arrays.asList ( new int[]{123,456} );
System.out.println (strings1);
List strings2 = Arrays.asList ( new Integer[]{123,456} );
System.out.println (strings2);
}
public static void main(String[] args) {
CollectionTest collectionTest = new CollectionTest ();
collectionTest.test1 ();
}
}
结果:
1035338341
123
Person{name='tom', age=20}
jenny
[aa, bb]
[[I@7699a589]
[123, 456]
遍历集合的方法:其中迭代器Iterator遍历只能遍历Set集合;
public void test2(){
Collection coll = new ArrayList ( );
coll.add(123);
coll.add ( new Person("tom",20) );
coll.add ( new java.lang.String ( "jenny" ) );
// 使用迭代器遍历对象
Iterator iterator = coll.iterator ();
while (iterator.hasNext ()){
System.out.println (iterator.next ());
}
}
public void test3(){
Collection coll = new ArrayList ( );
coll.add(123);
coll.add ( new Person("tom",20) );
coll.add ( new java.lang.String ( "jenny" ) );
// for(集合元素的类型 局部变量:集合对象)
for (Object object:coll){
System.out.println (object);
}
}
List集合:存储有序的、可重复的数据。ArrayList;LinkedList;Vector
ArrayList;LinkedList;Vector三者的异同?
相同点:三个类都是实现了List接口,存储数据的特点相同:存储有序的,可重复的数据。
不同点:ArrayList:作为List接口的主要实现类,线程不安全的,效率高;底层使用Object[]存储。
LinkedList:底层使用双向链表,对于频繁的插入、删除操作,使用此类比ArrayList的效率高。
Vector:作为List接口的古老实现类;线程安全的,效率低;底层使用Object[]存储。
Set集合:存储无序的、不可重复的数据。HashSet;TreeSet;LinkedHashSet
无序性:不等于随机性;存储的数据在底层数组中并非按照数组索引的顺序添加,而是按照数据的哈希值排列。
不可重复性:保证添加的元素按照equal()方法判断时,不能反悔true,即:相同的元素只能添加一个。
HashSet:作为Set接口的主要实现类,线程不安全的,效率高。
LinkedHashSet:作为HashSet的子类。
TreeSet:可以按照添加对象的指定属性,进行排序。
2.2、Map集合:
双列集合,用来存储一对(key-value)一对的数据。HashMap;LinkedHashMap;TreeMap;HashTable
①:HashMap:线程不安全的,效率高;存储null的key和value;
LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历。
原因:在原有的HashMap底层结构基础上,添加了一对指针,指向前一个和后一个元素。
TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。此时考虑key的自然排序或定制排序底层使用红黑树。
HashTable:线程安全的,效率低,不能存储null的key和value;
②:map结构的理解
Map中的key:无序的、不可重复的,使用set存储所有的key;key所在的类需要重写equal()方法以及hashCode()方法;(以HashMap为例)
Map中的value:无序的、可重复的,使用Collection存储所有的value;value所在的类需要重写equal()方法
一个键值对:key-value构成了一个entry对象;
Map中的entry:无序的、不可重复的,使用Set存储所有的entry;
③:HashMap的底层实现原理
1、在jdk7时候,HashMap在实例化以后,底层创建了长度为16的一维数组Entry[] table;
2、jdk8 相较于jdk7时候,在new HashMap()时没有创建一个长度为16的数组;jdk8底层的数组是Node[];在首次调用put()方法时,底层创建一个长度为16 的数组;jdk7底层结构只有数组+链表;而jdk8底层结构包括:数组+链表+红黑树。
④:HashMap的常用方法
Map map = new HashMap ( );
map.put ( "aa",123 );
map.put ( "aa",456 );
map.put ( "bb",123 );
// 遍历所有的key集合:keySet()
Set set = map.keySet ();
Iterator iterator = set.iterator ();
while (iterator.hasNext ()){
System.out.println (iterator.next ());
}
// 遍历所有的value元素:values
Collection values = map.values ();
for (Object object : values){
System.out.println (object);
}
// 遍历所有的key-value:entrySet
Set entrySet = map.entrySet ();
Iterator iterator1 = entrySet.iterator ();
while (iterator1.hasNext ()){
Object object1 = iterator1.next ();
Map.Entry entry = (Map.Entry) object1;
System.out.println (entry.getKey ()+"--------"+entry.getValue ());
}