一.Java集合概述

  • Java中的集合是工具类,可以存储任意数量的具有共同属性的对象

  • 集合的应用场景

    1.无法预测存储数据的数量

    2.同时存储具有一对一关系的数据

    3.需要进行数据的增删

    4.数据重复问题

  • 框架图

    Java-集合

二.集合框架的体系结构

  • Collection(主要存放类的对象)

    子接口(实现类) 描述
    List(ArrayList) 有序的,允许重复
    Queue(LinkedList) 有序的,允许重复
    Set(HashSet) 无序的,不允许重复
  • Map(主要存放键值对)

    • HashMap <Key,Value>

三.List(列表)

  • List是元素有序并且可以重复的集合,称为序列
  • List可以精确的控制每个元素插入位置,或删除某个位置的元素
  • List的主要实现类为ArrayList和LinkedList

ArrayList

  • ArrayList底层是由数组实现的(Arrays.aslist方法将数组转换为list)

  • 动态增长

  • 适合查找和更新元素

  • 元素可以为null

    常用方法 描述
    boolean add(E e) / add(int index, E element) 将指定的元素追加到此列表的末尾 / 指定位置
    int size() 返回此列表中的元素数
    E get(int index) 返回此列表中指定位置的元素
    E set(int index, E element)
    E remove(int index) / (Object o) 删除该列表中指定位置的元素
    boolean remove(Object o) 从列表中删除指定元素的第一个出现(如果存在)

四.Set

  • Set是元素无序并且不可以重复的集合,称为集

HashSet

  • 是Set的一个实现类(哈希集)

  • 只允许有一个null元素

  • 具有良好的存储和查找性能

  • 具体常用方法可查询Java api,与List相近

  • Iterator 迭代器接口

    • 以统一的方式对各种集合元素进行遍历(Set集合没有get方法,因此使用该接口)
    迭代器常用方法 描述
    boolean hasNext() 检测集合中是否还有下一个元素
    next() 返回集合中的下一个元素
  • 插入元素

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    public static void main(String[] args) {

    Set set = new HashSet();

    /**向Set集合插入元素*/
    set.add("hello");
    set.add("bye");
    set.add("how are you?");
    set.add("I'm fine");
    set.add("Thank you");
    //因为Set集合本身无序,不用考虑插入位置

    /**显示集合内容*/
    System.out.println("集合中元素为:");

    //将set中数据放入迭代器
    Iterator it = set.iterator();
    //遍历迭代器并输出元素
    while (it.hasNext()){
    System.out.print(it.next()+" ");
    }
    //若强行输出next()为空时会报错:Exception in thread "main" java.util.NoSuchElementException

    set.add("bye"); //插入重复元素不会报错,但也不会插入到Set集合中
    }
  • 上面说到不允许插入重复元素,那么来看下面的一个小例子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     public static void main(String[] args) {
    //定义手机类对象
    Phone huawei = new Phone("华为",3999,"Mate30");
    Phone xiaomi = new Phone("小米",3199,"MIX3");

    //放入HashSet
    Set set = new HashSet();
    set.add(huawei);
    set.add(xiaomi);

    //显示手机信息
    Iterator it = set.iterator();
    while (it.hasNext()){
    System.out.println(it.next());
    }

    //再添加一个重复类试试?
    Cat xiaomi1 = new Phone("小米",3199,"MIX3");
    set.add(xiaomi1);
    System.out.println("-----------------------");
    System.out.println("添加重复数据后手机信息");
    it = set.iterator();
    while (it.hasNext()){
    System.out.println(it.next());
    }
    }

    来看看运行结果:

    1
    2
    3
    4
    5
    6
    7
    8
    Phone{name='华为', price=3999, id='Mate30'}
    Phone{name='小米', price=3199, id='MIX3'}
    -----------------------
    添加重复数据后手机信息
    Phone{name='小米', price=3199, id='MIX3'}
    Phone{name='华为', price=3999, id='Mate30'}
    Phone{name='华为', price=3999, id='Mate30'}

    问题来了:为什么可以添加重复类呢?

    为了解决这个问题,我们要在实体类中重写equals和hashCode方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    //若两个对象的hashCode值一致,不用再调用equals方法
    @Override
    public boolean equals(Object o) {
    if(this == o)
    //若对象相等,返回true不用比较属性
    return true;
    //判断该类是否是手机类
    if(o.getClass()==Phone.class){
    //强制转换并比较属性
    Phone phone = (Phone)o;
    return phone.getName().equals(name)&&(phone.getPrice()==price)&&(phone.getId().equals(id));
    }
    return false;
    }

    @Override
    public int hashCode() {
    return Objects.hash(getName(), getPrice(), getId());
    }

  • 查找元素

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    //通过类名类查找
    if(set.contains(huawei)){
    System.out.println("找到了!======"+huawei);
    }else {
    System.out.println("没找到");
    }

    //使用名字属性查找
    boolean flag = false;
    Phone c = null;
    it=set.iterator();
    while (it.hasNext()){
    c = (Phone) it.next();
    if(c.getName().equals("xiaomi")){
    flag = true;
    break;
    }
    }
    if(flag){
    System.out.println("小米手机找到了!");
    System.out.println(c);
    }

五.Map

  • Map中的数据是以键值对(key-value)的形式存储的
  • key-value以Entry类型的对象实例存在
  • 可以通过key值快速查找value
  • 一个映射不能包含重复的键
  • 每个键最多映射一个值

HashMap

  • 基于哈希表的Map接口的实现

  • 允许使用null值和null键

  • key值不允许重复

  • HashMap中的Entry对象是无序排列的

    常用方法 描述
    V put(K key, V value) 将指定的值与此映射中的指定键相关联
    Set<Map.Entry<K,V>> entrySet() 返回Map中包含的映射(K+V)
    Collection<V> values() 返回Map中的值集合
    V get(Object key) 返回到指定键所映射的值
  • 代码案例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    public static void main(String[] args) {
    Map<String, String> animal = new HashMap<String,String>();
    System.out.println("请输入三组单词对应的注释,存放到HashMap中");
    Scanner console = new Scanner(System.in);
    //添加数据
    int i =0;
    while (i<3){
    System.out.println("请输入key值");
    String key = console.next();
    System.out.println("请输入value值");
    String value = console.next();
    animal.put(key,value);
    i++;
    }
    //打印输出value值(使用迭代器)
    System.out.println("-------使用迭代器输出value--------");
    Iterator<String> it = animal.values().iterator();
    while (it.hasNext()){
    System.out.print(it.next()+ " ");
    }
    System.out.println();
    //打印value+key值
    System.out.println("----------打印输出key+value值-----------");
    //通过entrySet方法
    System.out.println("通过entrySet方法得到key+value:");
    Set<Map.Entry<String, String>> entrySet = animal.entrySet();
    for(Map.Entry<String, String> entry : entrySet){
    System.out.println(entry.getKey() +"--"+entry.getValue());
    }

    System.out.println("-------------");
    //通过单词找到注释并输出
    //使用keySet方法
    System.out.println("输入你要查找的key名字:");
    String strSearch = console.next();
    //1.取得keySet
    Set<String> keySet = animal.keySet();
    //2.遍历keySet
    for(String key:keySet){
    if(strSearch.equals(key)){
    System.out.println("找到键值对为:"+key+"--"+animal.get(key) );
    break;
    }
    }
    }