java集合体系结构
这里只介绍常用的几个集合,它们本身都是实现类->ArrayList,LinkedList,HashMap,LinkedHashMap
-
Collection(单列集合)
- List(有序,可重复)
- ArrayList(底层是数组,查找快,增删慢)—>最常用
- LinkedList(底层是链表,查找慢,增删快)—>常用
- Set(无序,不可重复)—>很少用Set系列
- HashSet
- LinkedHashSet
- TreeSet
- HashSet
- List(有序,可重复)
-
Map(双列集合)
- HashMap–>最常用(无序)
- LinkedHashMap–>常用(有序)
- TreeMap
- HashMap–>最常用(无序)
介绍顺序
在最顶层的父接口Collection,Map中一定定义了所有子类集合的共同属性和方法,因此本文首先介绍Collection和Map中共性方法,然后再去针对每个子类集合介绍它的特有方法
Collection中的常用API
- boolean add(Object e): 向集合中添加元素
- boolean contains(Object o):判断集合中是否包含某个元素
- boolean isEmpty():判断集合中的元素是否为空
- boolean remove(Object o):根据元素的内容来删除某个元素
- int size():获取集合的长度
- void clear():清空集合中所有元素
- Object[] toArray():能够将集合转换成数组并把集合中的元素存储到数组中
public static void main(String[] args) {
//Collection c=new Collection();Collection是接口,不能new
//Collection c=new List();List也是接口,不能new
Collection c=new ArrayList();//ArrayList是实现类,可以new
System.out.println(c.add("java"));//返回true
c.add("node");
c.add("java");//允许重复
System.out.println(c.contains("node"));//判断集合中是否包含node,此时为true
System.out.println(c.isEmpty());//判断集合是否为空>此时为false
System.out.println("删除node元素前集合长度为:"+c.size());//3,这也验证了确实可以添加相同元素
c.remove("node");//删除集合中元素node,再次判断是否包含该元素
System.out.println(c.contains("node"));//判断集合中是否包含node,此时为false
System.out.println("删除node元素后集合长度为:"+c.size());//2
c.clear();// 清空集合
System.out.println("此时集合长度为:"+c.size());//0
}
- 这里单独演示一下toArray方法,挺好用的
Collection c = new ArrayList();
c.add("php");
c.add("node");
c.add("java");
Object[] array = c.toArray();// 集合转数组
// 遍历数组
for (Object obj : array) {
System.out.println(obj);
}
- 效果
php
node
java
迭代器
通用的遍历集合的手段
Collection c = new ArrayList();
c.add("php");
c.add("node");
c.add("java");
Iterator iterator = c.iterator();// 获取迭代器
while (iterator.hasNext()) {// 如果集合中下一个元素存在就继续迭代
System.out.println(iterator.next());// 取出元素,指针后移
}
- 与集合转数组遍历效果一样
使用迭代器的注意点
-
当使用迭代器遍历集合时,一旦使用集合中的 增加/删除 方法,会使得集合原有序列改变,导致并发修改异常
-
需要注意的是,上述情况指的是使用迭代器迭代集合的同时进行增加或删除操作才会发生异常,单独迭代或单独增加,删除不会有毛毛问题
-
避免也很容易,这里介绍三种
- 加个break
- 用迭代器自身操作进行(针对删除)
-
错误演示
Collection c = new ArrayList();
c.add("php");
c.add("node");
c.add("java");
Iterator iterator = c.iterator();// 获取迭代器
while (iterator.hasNext()) {// 如果集合中下一个元素存在就继续迭代
if(iterator.next().equals("java")) {
c.add("python");//java.util.ConcurrentModificationException
}
}
- 解决方法之break
- 解决方法之iterator自带remove
if (iterator.next().equals("java")) {
iterator.remove();
}
List中的常用API
- void add(int index, E element) :将元素添加到index索引位置上
- E get(int index) :根据index索引获取元素
- E remove(int index) :根据index索引删除元素
- E set(int index, E element):将index索引位置的的元素设置为element
List list = new ArrayList();
list.add(0, "殷素素");
list.add(0, "纪晓芙");// 同索引,覆盖
System.out.println(list.get(0));// 取出指定索引的元素,输出纪晓芙
System.out.println("被删除的元素是:" + list.remove(0));// 删除纪晓芙,自始至终和殷素素没毛毛关系,直接被覆盖了
list.add(1, "周芷若");
list.set(1, "赵敏");//替换指定索引的元素
System.out.println(list.get(1));//赵敏
LinkedList常用API
-
LinkedList底层使用的是链表结构,因此增删快,查询相对ArrayList较慢
-
void addFirst(E e) :向链表的头部添加元素
-
void addLast(E e):向链表的尾部添加元素
-
E getFirst():获取链头的元素,不删除元素
-
E getLast():获取链尾的元素,不删除元素
-
E removeFirst():返回链头的元素并删除链头的元素
-
E removeLast():返回链尾的元素并删除链尾的元素
-
这个不演示了,没毛毛东西
Map中的常用API
- put(K key, V value) :以键=值的方式存入Map集合
- get(Object key):根据键获取值
- int size():返回Map中键值对的个数
- boolean containsKey(Object key):判断Map集合中是否包含键为key的键值对
- boolean containsValue(Object value):判断Map集合中是否包含值为value键值对
- boolean isEmpty():判断Map集合中是否没有任何键值对
- void clear():清空Map集合中所有的键值对
- remove(Object key):根据键值删除Map中键值对
- Set<Map.Entry<K,V>> entrySet():将每个键值对封装到一个个Entry对象中,再把所有Entry的对象封装到Set集合中返回
- Set keySet() :将Map中所有的键装到Set集合中返回
- Collection values():返回集合中所有的value的值的集合
和上边的很多方法差不多,这里只介绍HashMap 和LinkedHashMap的遍历
Map<String , String > map = new HashMap<String , String >();
//方法一
for (String key : map.keySet()) {
String value=map.get(key);
System.out.println(key+":"+value);
}
//方法二
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey()+":"+entry.getValue());
}
Map<String , String > map = new LinkedHashMap<String , String >();
//方法一
for (String key : map.keySet()) {
String value=map.get(key);
System.out.println(key+":"+value);
}
//方法二
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey()+":"+entry.getValue());
}
二者差别在于遍历结果是否有顺序,LinkedHashMap的遍历结果与存入时的顺序一致