集合在JavaSE阶段是非常常见也非常重要的一个知识模块,在JavaEE中经常会有很多方法的返回值类型是集合,这篇博客介绍了一些Collection单列集合和Map双列集和的基础知识
1.Collection集合
1.Collection继承体系(单列集合,接口):List接口;Set接口;
a.List接口:
List接口的特点:有序--有索引---可以重复ArrayList
底层数据是数组--查询快--增删慢
线程不安全--效率高
LinkedList
底层数据是链表--查询慢--增删快
线程不安全--效率高
Vector
底层数据是数组--查询快--增删慢
线程安全--效率低
b.Set接口:HashSet类,LinkedHashSet类;(实现类)
Set集合的共性特点:唯一HashSet
底层数据是哈希表--查询和增删都比较快
无序--唯一,HashSet存储对象时,为了确保唯一性需要重写hashcode和equals方法:
先比较hashCode,效率高,equals方法效率低(优先判断)
如果对象hashCode不相等 直接添加到集合
如果对象hashCode相等再判断equals方法
如果相同 不添加(已经存在)
如果不同 添加
LinkedHashSet
底层数据是哈希表+链表
链表保证有序!!(所以不是所有的set集合都是无序的!) 哈希表保证元素唯一
存储无序,无索引,不重复.
可以通过JavaSEAPI文档查阅相关方法:
boolean add(E e) 确保此 collection 包含指定的元素(可选操作)。
Iterator<E> iterator() 返回在此 collection 的元素上进行迭代的迭代器。
int size() 返回此 collection 中的元素数。
2.Collection集合(遍历)
a.普通for循环
b.迭代器
Iterator<E> iterator();hasNext(),next();两个重要方法while循环遍历
并发修改异常(经常会抛出的异常)
集合在迭代的过程中,集合的长度发生了更改,会报此异常;
要想改集合长度,可使用Iterator的实现类ListIterator(集合框架)方法实现;
c.增强for循环(JDK1.5新特性)
for(集合中存储的数据类型 变量名:集合或者数组名称)底层使用迭代器方法,不能遍历时修改长度,也会并发修改异常;
3.集合泛型
ArrayList<String> list = new ArrayList<String>();<>中String即为泛型,前后泛型必须一致,或者后面的泛型可以不写(1.7版本新特性菱形泛型)
好处:a.不会报类型转换异常(前后泛型必须一致泛型)
b.避免向下转换这个过程
c.将运行时出现的异常提前到编译期,提高了安全性
泛型使用一般在集合中,也可以存在泛型方法和泛型接口
1.泛型类:在创建这个类的对象时确定了泛型
public class 类名<E>
2.泛型方法:在调用这个方法的时候确定了泛型的类型
3.泛型接口:在创建实现类的时候确定了泛型类型;
在创建实现类对象的时候确定了泛型类型;
通配符<?>
<? extends E>上线限定,E的子类
<? super E>下线限定,E的父类
2.Collections集合工具类
Collections.shuffle(List<?> list);打乱集合顺序
Collections.sort(List<?> list);
元素自然顺序(数字是从小到大)
Set集合无序,既不能打乱,也不能排序;
数组结构:一块连续的存储区域,查询速度快,添加速度慢
链表结构:每个元素指向下一个元素,添加删除快,查询修改慢
队列结构:容器先进先出的规则
栈结构:容器先进后出规则
3.Map接口
a.与Collection区别
Collection中的集合,元素是单列存在,是单列集合,一个一个元素方式存储;Map中的集合,元素是成对存在的,是双列集合,每个元素由键和值两部分构成;
Map中不能包含重复的键,每个键只对应一个值;
有两个实现类HashMap(重要常用),LinkedHashMap;
b.HashMap:
底层为Hash表结构,要保证键的唯一需要重写hashcode()和equals方法;LinkedHashMap:底层为Hash表+链表结构,元素存取一致;
c.Map遍历(如图,比较重要)
1.键找值方式:Set<key> set = map.keySet();
2.键值对方式
键和值一起作为Set集合元素存取
Set<Entry<key,value>> set = map.entrySet();
下面我写了一个简单的map集合两种遍历的方式
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class Map_Demo01 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
map.put("C", 4);//键重复时,值会覆盖
//第一种遍历(相当于一对夫妻,通过丈夫找到了妻子)
Set<String> keys = map.keySet();
for (String key : keys) {
//key为键 value为值
Integer value = map.get(key);
System.out.println(key+"---"+value);
}
System.out.println("----------华丽的分割线-----------");
//第二种遍历方式(先获取一对夫妻的结婚证,然后根据结婚证在获取丈夫和妻子)
Set<Entry<String, Integer>> es = map.entrySet();
for (Entry<String, Integer> en : es) {
String key = en.getKey();
Integer value = en.getValue();
System.out.println(key+"---"+value );
}
}
}