集合
Collection:集合层次中的根接口,JDK中没有提供该接口的直接实现类。
Java学习七——集合(2) - 图1

ArrayList 继承自 AbstractList,实现了 List 接口。底层基于数组实现容量大小动态变化。允许 null 的存在,支持快速访问、复制、序列化的。它提供的功能类似Vector类但不同步,它是以Array方式实现的List,允许快速随机存取,不指定泛型时可以存放所有引用数据类型(包括基本数据类型的包装类)。特点是读快改慢。

Vector是一种老的动态数组,是线程同步的,效率很低,一般不赞成使用。

LinedList 实现一个链表,提供最佳顺序存取,适合插入和删除元素。由这个类定义的链表也可以像栈或队列一样被使用,提供最佳顺序存取,适合插入和删除元素。特点是改快读慢。

获取迭代器对象:Iterator iterator = Collection.iterator();

在获取完迭代器对象后,不能用集合的对象执行删除,会改变集合的原有状态,用迭代器本身的方法进行删除,
例如:iterator.remove()。那这是为什么?

  • Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。
    所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性

contains方法:collection.contains() 检查集合对象中是否包含某一元素

在学习contains方法之前,先了解一下String m1 = new String (“abc”)在虚拟机中是怎么执行的:

Java学习七——集合(2) - 图2

先在栈内存中为m1开辟一片内存空间,里面是地址值,指向堆内存中的new String();,堆内存中也有一个地址值,指向方法区中的字符串”abc”
若是是String x = “abc”,则x的内存空间里的地址值指向方法区中的”abc”。

contains方法的底层是equals方法,equals方法来自Object类,只比较地址,地址不同直接返回false;但String类将equals方法进行了重写,先比较对象的地址,若地址相同,返回true,若地址不同,判断是否为String类后比较对象的内容,若内容相同,也返回true。即若当前类没有重写equals方法,则比较的是地址值,若重写了,比较的是内容。

**泛型:


指定集合去存储某一类型数据。**
泛型是可以自己定义的,map的key和value也可以自己指定类型。
泛型当中也可以体现多态

  1. //Rabbit实现了animal接口
  2. ArrayList<Animal> arrayList = new ArrayList();
  3. arrayList.add(new Rabbit());

Map:

map集合也是个接口,即不能实例化对象。
map集合包含key-value对,key不能重复
创建map集合对象时需要new一个map子类的对象
如:Map map = new HashMap():

map集合的常用方法

1、添加元素

map.put(key,value)

2、删除元素

(1)根据key来删除value

map.remove(key)

(2)将key与value都传入进行删除(因为map集合key不能重复,所以没必要)

map.remove(key,value)

3、根据key获取元素的value

map.get(key)

4、遍历集合

注意:和Collection集合没一点关系,map集合是不能获取迭代器对象的。map集合有自己的遍历方式。

(1)map集合第一种遍历方式:map.keyset()
Set set = map.keyset();
先获取map集合的所有key,将这些可以转成set集合。因为set集合是Collection接口体系下的,所以可以通过迭代器进行遍历。

  1. Interator interator = set.iterator();
  2. while(iterator.hasNext()){ //遍历
  3. Object key = iterator.next();
  4. Object value = map.get(key); //通过key获取value
  5. System.out.printfln(key); //输出value

(2)map集合第二种遍历方式:map.entrySet(); (将map集合转换成set集合)返回的也是Set集合
Set set = map.entrySet();

map.entry()的底层代码一部分是Set> entrySet();可以看出这是一个泛型,其中的Map.Entry是一个静态内部类的形式,K,V则是自定义数据类型,传入什么类型就是什么类型。

加强for循环进行遍历集合

  1. for(声明语句: 表达式){
  2. //代码句子
  3. }

声明语句:声明新的局部变量,该变量的类型必须和集合元素的类型匹配。其作用域限定在循环语句块,其值与此时集合元素的值相等。

表达式:表达式是要访问的集合名,或者是返回值为集合的方法。

  1. for (Object o : list) {
  2. System.out.println(o);
  3. }


举个例子:

  1. //创建集合对象
  2. HashMap<String , Integer> map = new HashMap<>();
  3. map.put("a",20);
  4. map.put("b",23);
  5. map.put("c",25);
  6. map.put("d",27);
  7. //遍历集合
  8. Set<Map.Entry<String, Integer>> entries = map.entrySet();
  9. //通过加强for循环遍历集合
  10. for(Map.Entry<String, Integer> entry : entries){
  11. System.out.println(entry.getKey()+""+entry.getValue());
  12. }