集合由来:
数组长度是固定的,当添加的元素长度超过数组长度时需重新定义数组
因此java内部提供了集合类,可存储任意对象,长度也可以改变,随元素的增减而增减

集合、数组区别:

  • 数组:可存储基本数据类型(存储的是值),也可存储引用数据类型(存储的是地址值);长度固定不可变
  • 集合:只能存储引用数据类型(即对象),可存储基本数据类型,存储时自动装箱成对象;长度可变,随元素增减

使用场合:

  • 数组:元素个数固定,则使用数组
  • 集合:元素个数不固定,则使用集合

例子

  • 公共实体类
package cn.chen.demo;

public class Person {
    private String name;
    private int age;
    public String getName() {
          return name;
    }
    public void setName(String name) {
           = name;
    }
    public int getAge() {
          return age;
    }
    public void setAge(int age) {
          this.age = age;
    }

    public Person(String name, int age) {
          super();
           = name;
          this.age = age;
    }
    @Override
    public String toString() {
          return "Person [name=" + name + ", age=" + age + "]";
    }
}
  • 简单数组
package cn.chen.demo;

public class Demo_Simple {

    public static void main(String[] args) {
         demo1();
         demo2();
    }
    private static void demo1() {
         int[] arr = new int[3];//创建基本数据类型数组
         arr[0] = 3;
         arr[1] = 4;
         arr[2] = 2;
         System.out.print("基本数据类型数组:");
         for(int i =0 ;i<arr.length;i++){
              System.out.print(arr[i]+",");
         }
         System.out.println();
   }
    private static void demo2() {
         Person[] p = new Person[3];//创建引用数据类型数组
         p[0]=new Person("张三",21);
         p[1]=new Person("李四",20);
         p[2]=new Person("王五",20);
         System.out.print("引用数据类型数组:");
         for(int i = 0 ;i<p.length;i++){
              System.out.print(p[i]+ ",");
         }
         System.out.println();
   }
}
运行结果:
基本数据类型数组:3,4,2,
引用数据类型数组:Person [name=张三, age=21],Person [name=李四, age=20],Person [name=王五, age=20],
  • Collection
package cn.chen.demo;

import java.util.ArrayList;
import java.util.Collection;

/**
 *  collectionXxx.java使用了未经检查或不安全的操作.
    注意:要了解详细信息,请使用 -Xlint:unchecked重新编译.java编译器认为该程序存在安全隐患
    温馨提示:这不是编译失败,可以先不用理会,学了泛型就理解了
    add方法:如果是List集合一直都返回true,因为List集合中是可以存储重复元素的;如果是Set集合当存储重复元素的时候,就会返回false
    ArrayList的父类的父类重写toString方法,所以在打印对象的引用的时候,输出的结果不是Object类中toString的结果
* 方法
    boolean add(E e)           //添加元素
    int size()                 //集合长度
    boolean remove(Object o)   //删除指定元素
    boolean contains(Object o) //判断是否包含该元素
    boolean isEmpty()          //判断集合是否为空
    void clear()               //清空集合
*/
public class Demo_Collection {
    public static void main(String[] args) {
        col1();
  }
  private static void col1() {
        Collection c =new ArrayList();
        c.add("1");
        c.add("2");
        c.add("3");
        c.add("4");
        c.add("5");

        System.out.println("集合长度(元素个数):"+c.size());//集合长度
        System.out.println("集合元素:"+c);

        c.remove("4");//移除指定元素
        System.out.println("------------ remove后 ----------");
        System.out.println("集合长度(元素个数):"+c.size());
        System.out.println("集合元素:"+c);

        System.out.println("------------ 判断是否包含 ----------");
        System.out.println("不包含:"+c.contains("4"));//判断是否包含该元素
        System.out.println("包含:"+c.contains("3"));

        System.out.println("------------ 判断集合是否为空 ----------");
        System.out.println("不为空:"+c.isEmpty());
        c.clear();//清空集合
        System.out.println("------------ clear后 ----------");
        System.out.println("集合长度(元素个数):"+c.size());

        System.out.println("------------ 判断集合是否为空 ----------");
        System.out.println("为空:"+c.isEmpty());

  }
}

带ALL功能

package cn.chen.demo;

import java.util.ArrayList;
import java.util.Collection;

public class Demo_Collection_2 {
    /**带All的功能
        boolean addAll(Collection c)           // 将c2中的每一个元素添加到c1中
        boolean removeAll(Collection c)        //删除交集
        boolean containsAll(Collection c)      //判断调用的集合是否包含传入的集合
        boolean retainAll(Collection c)        //判断是否是交集
    */  
    public static void main(String[] args) {
        demo1();
        demo2();
        demo3();
        demo4();

  }
  private static void demo1() {
        Collection c1 = new ArrayList();
        Collection c2 = new ArrayList();
        c1.add("1");
        c1.add("2");
        c1.add("3");
        c2.add("2");
        c2.add("4");
        boolean c = c1.containsAll(c2);//判断调用的集合是否包含传入的集合
        System.out.println("判断是否包含:"+c);

  }
  private static void demo2() {
        Collection c1 = new ArrayList();
        Collection c2 = new ArrayList();
        c1.add("1");
        c1.add("2");
        c1.add("3");
        //c2.add(c1);      //输出结果为  [[1, 2, 3]] 这里是将整个c1当成一个对象添加到c2中去
        c2.addAll(c1);     //输出结果为  [1, 2, 3]  这里是将c1的每一个元素都添加到c2中去
        System.out.println("c2集合元素:"+c2);
  }
  private static void demo3() {
        Collection c1 = new ArrayList();
        Collection c2 = new ArrayList();
        c1.add("1");
        c1.add("2");
        c1.add("3");
        c2.add("2");
        c1.removeAll(c2);//删除交集
        System.out.println("删除交集之后结果:"+c1);
  }
  private static void demo4() {
        Collection c1 = new ArrayList();
        Collection c2 = new ArrayList();
        c1.add("1");
        c1.add("2");
        c1.add("3");
        c2.add("2");
        c2.add("4");
        boolean b = c1.retainAll(c2);//判断是否是交集
        System.out.println("判断是否存在交集:"+b+",取交集:"+c1);

  }
}
运行结果:
判断是否包含:false
c2集合元素:[1, 2, 3]
删除交集之后结果:[1, 3]
判断是否存在交集:true,取交集:[2]

集合转数组

package cn.chen.demo;

import java.util.ArrayList;
import java.util.Collection;

public class Demo_Collection_3 {
    //集合转数组
    public static void main(String[] args) {
        Collection c = new ArrayList();
        c.add(new Person("张三",12));
        c.add(new Person("李四",15));
        c.add(new Person("王五",17));
        Object[] o = c.toArray();//集合转换成数组
        for(int i=0;i<c.size();i++){
             Person p = (Person) o[i];//向下转型,将Object强转为Person类型
             System.out.println(p.getName()+","+p.getAge());
        }
  }    
}
运行结果:
张三,12
李四,15
王五,17

迭代器
原理:迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法,这样做是可以的,但是会让整个集合体系过于臃肿,迭代器是将这样的方法向上抽取出接口,然后在每个类的内部,定义自己迭代方式,这样做的好处有二,第一规定了整个集合体系的遍历方式都是hasNext()和next()方法,第二,代码有底层内部实现,使用者不用管怎么实现的,会用即可

package cn.chen.demo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Demo_Collection_4 {
     public static void main(String[] args) {
         demo1();
         demo2();

   }
   private static void demo1() {
         Collection c = new ArrayList();
         c.add(new Person("张三",34));
         c.add(new Person("李四",28));
         c.add(new Person("王五",26));
         c.add(new Person("赵六",32));
         Iterator it = c.iterator();//获取迭代器
         //对集合中的元素迭代(遍历)
         while(it.hasNext()){//判断集合中是否有元素,有就返回true
              System.out.println(it.next());
         }
   }

   private static void demo2() {
         Collection c = new ArrayList();
         c.add(new Person("张三",34));
         c.add(new Person("李四",28));
         c.add(new Person("王五",26));
         c.add(new Person("赵六",32));
         Iterator it = c.iterator();//获取迭代器
         while(it.hasNext()){//判断集合中是否有元素,有就返回true
              Person p =(Person) it.next();//向下转型
              System.out.println(p.getName()+","+p.getAge());
         }

   }

}
运行结果:
Person [name=张三, age=34]
Person [name=李四, age=28]
Person [name=王五, age=26]
Person [name=赵六, age=32]
张三,34
李四,28
王五,26
赵六,32
  • List
package cn.chen.demo;

import java.util.ArrayList;
import java.util.List;

public class Demo_List_1 {
    /**
     *  void add(int index,E element)
        E remove(int index)
        E get(int index)
        E set(int index,E element)
     */
    // index<=size并且index>=0都不会报异常
    // java.lang.IndexOutOfBoundsException,当存储时使用不存在的索引时
    public static void main(String[] args) {
        List l = new ArrayList();
        l.add("1");//添加元素
        l.add("2");
        l.add("3");
        l.add("4");
        l.add("5");
        System.out.println("数组:"+l);
        Object o = l.remove(1);//根据索引删除元素
        System.out.println("被删除元素:"+ o +",删除指定索引后数组:"+l);
        l.set(1, "8");//根据索引修改元素
        System.out.println("修改指定索引后数组:"+l);
        System.out.print("遍历数组:");
        //通过索引遍历List集合
        for(int i = 0; i<l.size();i++){
             System.out.print(l.get(i)+" ");//取元素
        }
  }
}
运行结果:
数组:[1, 2, 3, 4, 5]
被删除元素:2,删除指定索引后数组:[1, 3, 4, 5]
修改指定索引后数组:[1, 8, 4, 5]
遍历数组:1 8 4 5
  • Iterator和ListIterator
    迭代器修改元素(ListIterator的特有功能add)
package cn.chen.demo.iterator;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class Demo_Iterator_1 {
    public static void main(String[] args) {
        List l = new ArrayList();
        l.add("陈陈");
        l.add("沉沉");
        l.add("辰辰");
        l.add("尘尘");
        l.add("臣臣");
        demo(l);

    }
    private static void demo(List l) {
        ListIterator li = l.listIterator();//获取迭代器(List集合特有的)
        while(li.hasNext()){
             String str = (String) li.next();
             if("沉沉".equals(str)){
                  li.add("小北");// //遍历的同时在增加元素,并发修改java.util.ConcurrentModificationException
             }
        }
        System.out.println("ListIterator:"+l);
    }
}
运行结果:
ListIterator:[陈陈, 沉沉, 小北, 辰辰, 尘尘, 臣臣]

ListIterator 向前移、向后移(向前移情况下,必须是先向后移,前面有元素才有用)

package cn.chen.demo.iterator;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class Demo_Iterator_2 {
    public static void main(String[] args) {
        List l = new ArrayList();
        l.add("陈陈");
        l.add("沉沉");
        l.add("辰辰");
        l.add("尘尘");
        l.add("臣臣");
        ListIterator li = l.listIterator();
         System.out.print("获取元素且将指针向后移:");
        while(li.hasNext()){
             System.out.print(li.next()+",");
        }
        System.out.println();
        System.out.print("获取元素且将指针向前移:");
        while(li.hasPrevious()){
             System.out.print(li.previous()+",");
        }

    }

}
运行结果:
获取元素且将指针向后移:陈陈,沉沉,辰辰,尘尘,臣臣,
获取元素且将指针向前移:臣臣,尘尘,辰辰,沉沉,陈陈,

  • A:数组
  • 查询快修改也快
  • 增删慢
  • B:链表
  • 查询慢,修改也慢
  • 增删快
  • List的三个子类特点
  • ArrayList:
    底层数据结构是数组,查询快,增删慢。
    线程不安全,效率高。
  • Vector:
    底层数据结构是数组,查询快,增删慢。
    线程安全,效率低。
    Vector相对ArrayList查询慢(线程安全的)
    Vector相对LinkedList增删慢(数组结构)
  • LinkedList:
    底层数据结构是链表,查询慢,增删快。
    线程不安全,效率高。
  • 区别
  • Vector和ArrayList的区别
    Vector是线程安全的,效率低
    ArrayList是线程不安全的,效率高
    共同点:都是数组实现的
  • ArrayList和LinkedList的区别
    ArrayList底层是数组结果,查询和修改快
    LinkedList底层是链表结构的,增和删比较快,查询和修改比较慢
    共同点:都是线程不安全的
  • 使用场合
  • 查询多用ArrayList
  • 增删多用LinkedList
  • 如果都多ArrayList
  • foreach
    增强for:简化数组和Collection集合的遍历
    格式:
for(元素数据类型 变量 : 数组或者Collection集合) {
        使用变量即可,该变量就是元素
    }

好处:简化遍历
增强for循环底层依赖的是迭代器(Iterator)

  • set
    TreeSet 是一个有序的集合,它的作用是提供有序的Set集合。它继承于AbstractSet抽象类,实现了NavigableSet,Cloneable,java.io.Serializable接口。
package cn.chen.demo;

import java.util.TreeSet;

public class Demo_TreeSet {
    public static void main(String[] args) {
        TreeSet ts = new TreeSet();
        ts.add(12);
        ts.add(14);
        ts.add(43);
        ts.add(27);
        ts.add(32);
        System.out.println(ts);
    }
}
运行结果:
[12, 14, 27, 32, 43]

三者比较:
1.List
a. 普通for循环, 使用 get() 逐个获取
b. 调用 iterator() 方法得到 Iterator, 使用 hasNext() 和 next() 方法
c. 增强for循环, 只要可以使用 Iterator 的类都可以用
d. Vector 集合可以使用 Enumeration 的 hasMoreElements() 和 nextElement() 方法

2.Set
a. 调用 iterator() 方法得到 Iterator , 使用 hasNext() 和 next() 方法
b. 增强for循环, 只要可以使用 Iterator 的类都可以用

3.普通for循环,迭代器,增强for循环是否可以在遍历的过程中删除
a. 普通for循环:可以删除,但是索引要 – (减减)
b. 迭代器:可以删除,但是必须使用迭代器自身的 remove 方法,否则会出现并发修改异常
c. 增强for循环:不能删除


  • Map
    概述:
  • 将键映射到值的对象
  • 一个映射不能包含重复的键
  • 每个键最多只能映射到一个值

Map接口和Collection接口的不同:

  • Map是双列的, Collection是单列的
  • Map的键唯一, Collection的子体系Set是唯一的
  • Map集合的数据结构值针对键有效,跟值无关; Collection集合的数据结构是针对元素有效

Map集合的功能概述

  • a:添加功能
  • V put(K key,V value):添加元素。
  • 如果键是第一次存储,就直接存储元素,返回null
  • 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
  • b:删除功能
  • void clear():移除所有的键值对元素
  • V remove(Object key):根据键删除键值对元素,并把值返回
  • c:判断功能
  • boolean containsKey(Object key):判断集合是否包含指定的键
  • boolean containsValue(Object value):判断集合是否包含指定的值
  • boolean isEmpty():判断集合是否为空
  • d:获取功能
  • Set