Java 集合框架
数组存储多个数据方面的弊端:
①数组一旦初始化,其长度就不可变了。
②数组中存储数据特点的单一性,对于无序的,不可重复的场景的多个数据就无能为力
③数组中可用的方法、属性、都极少,具体的需求,都需要自己来组织相关代码逻辑
数组的优点
①元素类型既可以是基本数据类型,也可以是引用数据类型
一、Java集合框架体系
1.java.util.Collection:存储一个一个的数据
java
public void test(){
Collection collection=new ArrayList();
//add()
collection.add("AA");
collection.add(123);
collection.add(112.2323);
//[AA, 123, 112.2323]
System.out.println(collection);
//addAll(Collection all)
Collection addColl = new ArrayList();
addColl.add("12345");
addColl.add(123456);
collection.addAll(addColl);
//[AA, 123, 112.2323, 12345, 123456]
System.out.println(collection);
//size()
//5
System.out.println(collection.size());
//isEmpty(),判断是否为空
//false
System.out.println(collection.isEmpty());
//contains(),是都包含某个元素
//true
System.out.println(collection.contains("12345"));
//false
System.out.println(collection.contains(collection.contains(12345)));
//containsAll(Collection coll) 是否包含一个集合
//equals(Object obj)
//clear() 清空
collection.clear();
//[]
System.out.println(collection);
//remove(Object obj) 删除,一旦找到元素就停止
//removeAll(Object obj)删除所有的指定元素
//Object[] toArray 转换为数组
Collection coll=new ArrayList();
coll.add("111");
coll.add("222");
Object[] arr=coll.toArray();
//[111, 222]
System.out.println(Arrays.toString(arr));
//hashCode() 计算哈希值
//iterator 返回迭代器对象,用于集合遍历
}
集合与数组的转换
java
public void test2(){
//数组->集合
String[] arr=new String[]{"A","B","C"};
Collection list=Arrays.asList(arr);
//集合->数组
Collection coll=new ArrayList();
coll.add("111");
coll.add("222");
Object[] arr2=coll.toArray();
}
向Collection添加元素的类的要求:
要重写equals方法,以为在调用contains()/remove()在使用时,要调用元素所在类的equals();
迭代器
java
public void test3(){
Collection coll=new ArrayList();
coll.add(1);
coll.add(2);
coll.add(3);
Iterator iterator=coll.iterator();
while (iterator.hasNext()){
//next() ①指针下移②将下移以后得集合位置上的元素返回
System.out.println(iterator.next());
}
}
增强for循环(forEach)
java
Collection coll=new ArrayList();
coll.add(1);
coll.add(2);
coll.add(3);
for (Object obj : coll){
System.out.println(obj);
}
增强for循环的执行过程中,是将集合或数组中的元素依次赋值给临时变量,注意。循环体中对临时变量的修改,可能不会导致原来集合或数组中元素的修改
子接口:List
存储有序的、可重复的数据("动态数组")
①ArrayList(主要实现类)
List的主要实现类,线程不安全,效率高,底层使用的Object[ ]数组存储,在添加数据、查找数据时效率较高;在插入、删除数据时效率低
②LinkedList
底层使用双向链表的方式进行存储;在对集合中的数据进行频繁的删除。插入操作时,建议使用此类
③Vector
List古老的实现类,线程安全,效率低,底层使用的Object[ ]数组存储
子接口:Set
存储无序的、不可重复的数据,一般用来过滤重复数据
1.无序性:
不等于随机性
添加元素的顺序和遍历顺序不一致,也不是无序性
无序性与添加元素的位置有关,不像ArrayList一样是依次紧密排列的。这里是根据添加的元素的哈希值,计算其在数组中的存储位置,此位置不是依次紧密排列的,表现为无序性
2.不可重复性
添加到Set中的元素不能相同的,比较的标准,需要判断hashCode()得到的哈希值以及equals()得到的boolean型的结果。哈希值相同且equals返回true,则认为元素是相同的
添加到HashSet/LinkedHashSet中元素的要求:
要求元素所在的类重写equals()和hashCode(),同时,要求equals()和hashCode()要保持一致性!我们只需要在IDEA中自动生成两个方法重写即可,即能保证两个方法的一致性
①HashSet(主要实现类)
底层使用的是HashMap,即使用数组+单向链表+红黑树结构进行存储
②LinkedHashSet
是HashSet的子类,在使用数组+单向链表+红黑树结构进行存储的基础上,又添加了一组双向链表,用于记录添加元素的先后顺序,即,我们可以按照添加元素的顺序进行遍历。便于频繁的查询操作
③TreeSet
底层使用红黑树存储,可以按照添加的元素的指定的属性的大小顺序进行遍历
要求添加到TreeSet中的元素必须是同一类型的对象,否则会报ClassCastException
判断数据是否相同的标准
不再是考虑hashCode()和equals()方法,也就意味着添加到TreeSet中的元素所在的类不需要重写hashCode()和equals()方法;比较元素大小或比较元素是否相等的标准就是考虑自然排序或定制排序中,compareTo()和compare()的返回值。如果compareTo()或compare()的返回值为0,则认为两个对象是相等的,由于TreeSet中不能存放相同的元素,则后一个相等的元素就不能添加到TreeSet中。
2.java.util.Map:存储一对一的数据(key-value键值对)
①HashMap(主要实现类)
线程不安全,效率高,可以添加null的key和value值;底层使用数组+单向链表+红黑树接口存储(JKD8)
HashMap的特点
HashMap中所有的key彼此之间是不可重复的、无序的。所有的key就构成一个set集合。key所在的类要重写hashCode()和equals();
HashMap中所有的value彼此之间是可重复的、无序的。所有的value就构成一个Collection集合。value所在的类要重写equals()
HashMap中的一个key-value,就构成一个entry,HashMap中所有entry是不可重复的、无序的。所有entry就构成一个Set集合
②LinkedHashMap
是HashMap的子类;在HashMap使用的数据结构的基础上,增加了一对双向链表,用于记录添加元素的先后顺序,进而我们在遍历元素时,可以按照添加顺序显示。
开发中对于频繁的遍历操作,建议使用此类
③TreeMap
底层使用红黑树存储;可以按照添加元素的指定属性的大小顺序进行遍历。
需要考虑使用:1.自然排序 2.定制排序
④Hashtable(古老实现类)
线程安全,效率低,不可以添加null的key和value值,底层使用数组+单向链表结构存储(JKD8)
⑤Properties
是Hashtable的子类,其key和value都是String类型,常用来处理属性文件
二、Collections工具类
1.Collections概述
Collections是一个操作Set、List、Map等集合类。
2.常用方法
3.面试题:区分Collection和Collections
Collection:集合框架中的用于存储的一个元素接口,又分为List和Set等子接口
Collections:用于操作集合的一个工具类,此时的几个框架包括:Set、List、Map