集合

Java 集合
Collection 集合
1.1 集合概述
集合:集合是 java 中提供的一种容器,可以用来存储多个数据。
1.2 集合框架
JAVASE 提供了满足各种需求的 API,在使用这些 API 前,先了解其继承与接口操作架构,才
能了解何时采用哪个类,以及类之间如何彼此合作,从而达到灵活应用。
集合按照其存储结构可以分为两大类,分别是单列集合 java.util.Collection 和双列集合
java.util.Map
Collection:单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的
子接口,分别是 java.util.List 和 java.util.Set。其中,List 的特点是元素有序、元素
可 重 复 。 Set 的 特 点 是 元 素 无 序 , 而 且 不 可 重 复 。 List 接 口 的 主 要 实 现 类 有
java.util.ArrayList 和 java.util.LinkedList , Set 接 口 的 主 要 实 现 类 有
java.util.HashSet 和 java.util.TreeSet。
1.3 Collection 常用功能
Collection 是所有单列集合的父接口,因此在 Collection 中定义了单列集合(List 和 Set)
通用的一些方法,这些方法可用于操作所有的单列集合。方法如下:

  • public boolean add(E e): 把给定的对象添加到当前集合中 。
  • public void clear() :清空集合中所有的元素。
  • public boolean remove(E e): 把给定的对象在当前集合中删除。
  • public boolean contains(E e): 判断当前集合中是否包含给定的对象。
  • public boolean isEmpty(): 判断当前集合是否为空。
  • public int size(): 返回集合中元素的个数。
  • public Object[] toArray(): 把集合中的元素,存储到数组中。
    方法演示:
    public class Demo01Collection {
    public static void main(String[] args) {
    //创建集合对象,可以使用多态
    //Collection coll = new ArrayList<>();
    Collection coll = new HashSet<>();
    System.out.println(coll);//重写了 toString 方法 []
    /*
    public boolean add(E e): 把给定的对象添加到当前集合中 。
    返回值是一个 boolean 值,一般都返回 true,所以可以不用接收
    /
    boolean b1 = coll.add(“张三”);
    System.out.println(“b1:”+b1);//b1:true
    System.out.println(coll);//[张三]
    coll.add(“李四”);
    coll.add(“李四”);
    coll.add(“赵六”);
    coll.add(“田七”);
    System.out.println(coll);//[张三, 李四, 赵六, 田七]
    /

    public boolean remove(E e): 把给定的对象在当前集合中删除。
    返回值是一个 boolean 值,集合中存在元素,删除元素,返回 true
    集合中不存在元素,删除失败,返回 false
    /
    boolean b2 = coll.remove(“赵六”);
    System.out.println(“b2:”+b2);//b2:true
    boolean b3 = coll.remove(“赵四”);
    System.out.println(“b3:”+b3);//b3:false
    System.out.println(coll);//[张三, 李四, 田七]
    /

    public boolean contains(E e): 判断当前集合中是否包含给定的对象。
    包含返回 true
    不包含返回 false
    */
    boolean b4 = coll.contains(“李四”);
    System.out.println(“b4:”+b4);//b4:true
    boolean b5 = coll.contains(“赵四”);
    System.out.println(“b5:”+b5);//b5:false
    //public boolean isEmpty(): 判断当前集合是否为空。 集合为空返回 true,集
    合不为空返回 false
    boolean b6 = coll.isEmpty();
    System.out.println(“b6:”+b6);//b6:false
    //public int size(): 返回集合中元素的个数。
    int size = coll.size();
    System.out.println(“size:”+size);//size:3
    //public Object[] toArray(): 把集合中的元素,存储到数组中。
    Object[] arr = coll.toArray();
    for (int i = 0; i < arr.length; i++) {
    System.out.println(arr[i]);
    }
    //public void clear() :清空集合中所有的元素。但是不删除集合,集合还存在
    coll.clear();
    System.out.println(coll);//[]
    System.out.println(coll.isEmpty());//true
    }
    }
    Iterator 迭代器
    2.1 Iterator 接口
    在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK 专门提供了一个接口
    java.util.Iterator。Iterator 接口也是 Java 集合中的一员,但它与 Collection、Map 接
    口有所不同,Collection 接口与 Map 接口主要用于存储元素,而 Iterator 主要用于迭代访
    问(即遍历)Collection 中的元素,因此 Iterator 对象也被称为迭代器。
    想要遍历 Collection 集合,那么就要获取该集合迭代器完成迭代操作。获取迭代器的方法:
  • public Iterator iterator(): 获取集合对应的迭代器,用来遍历集合中的元素的。
    迭代的概念:
    迭代:即 Collection 集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,
    如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有
    元素全部取出。这种取出方式专业术语称为迭代。
    Iterator 接口的常用方法如下:
  • public E next():返回迭代的下一个元素。
  • public boolean hasNext():如果仍有元素可以迭代,则返回 true。
    案例:
    public class IteratorDemo {
    public static void main(String[] args){
    ArrayList arr = new ArrayList();
    //往集合里面去添加元素
    arr.add(“111”);
    arr.add(“222”);
    arr.add(“333”);
    //是使用集合里面的一个 iterator()来获取迭代器里面的对象,iterator 接口来
    接收
    //注意的地方;Iterator 接口是泛型的,迭代器的泛型是跟着集合走的
    Iterator iter = arr.iterator();
    while (iter.hasNext()){
    String a = iter.next();
    System.out.println(a);
    }
    // System.out.println(arr);
    // Iterator iter = arr.iterator();
    // boolean a = iter.hasNext();
    // String b = iter.next();
    // System.out.println(b);
    //
    // boolean c = iter.hasNext();
    // System.out.println©;
    // String d = iter.next();
    // System.out.println(d);
    //
    // boolean e = iter.hasNext();
    // System.out.println(e);
    // String f = iter.next();
    // System.out.println(f);
    //
    // boolean g = iter.hasNext();
    // System.out.println(e);
    // String h = iter.next();//NoSuchElementException
    // System.out.println(f);
    }
    }

tips::在进行集合元素取出时,如果集合中已经没有元素了,还继续使用迭代器的 next
方法,将会发生 java.util.NoSuchElementException 没有集合元素的错误。
2.2 迭代器的实现原理
当遍历集合时,首先通过调用t集合的iterator()方法获得迭代器对象,然后使用hashNext()
方法判断集合中是否存在下一个元素,如果存在,则调用 next()方法将元素取出,否则说
明已到达了集合末尾,停止遍历元素。
Iterator 迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素。
在调用 Iterator 的 next 方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,
当第一次调用迭代器的 next 方法后,迭代器的索引会向后移动一位,指向第一个元素并将
该元素返回,当再次调用 next 方法时,迭代器的索引会指向第二个元素并将该元素返回,
依此类推,直到 hasNext 方法返回 false,表示到达了集合的末尾,终止对元素的遍历。
2.3 增强 for 循环
增强 for 循环(也称 for each 循环)是JDK1.5以后出来的一个高级 for 循环,专门用来
遍历数组和集合的。它的内部原理其实是个 Iterator 迭代器,所以在遍历的过程中,不能
对集合中的元素进行增删操作。
格式:
for(元素的数据类型 变量 : Collection 集合 or 数组){
//写操作代码
}
它用于遍历 Collection 和数组。通常只进行遍历元素,不要在遍历的过程中对集合元素进
行增删操作。
tips: 新 for 循环必须有被遍历的目标。目标只能是 Collection 或者是数组。新式 for
仅仅作为遍历操作出现。
List 接口介绍
java.util.List 接口继承自 Collection 接口,是单列集合的一个重要分支,习惯性地会将
实现了 List 接口的对象称为 List 集合。在 List 集合中允许出现重复的元素,所有的元素
是以一种线性方式进行存储的,在程序中可以通过索引来访问集合中的指定元素。另外,List
集合还有一个特点就是元素有序,即元素的存入顺序和取出顺序一致。
List 接口特点:

  1. 它是一个元素存取有序的集合。例如,存元素的顺序是 11、22、33。那么集合中,元素
    的存储就是按照 11、22、33 的顺序完成的)。
  2. 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是
    一个道理)。
  3. 集合中可以有重复的元素,通过元素的 equals 方法,来比较是否为重复的元素。
    3.2 List 接口中常用方法
    1.添加
    add(E e)
    addAll(Collection<? extends E> c)
    2.删除
    clear
    remove(Object o)
    removeAll(Collection<?> c)
    retainAll(Collection<?> c)
    3.判断
    contains(Object o)
    containsAll(Collection<?> c)
    equals(Object o)
    isEmpty()
    4 获取
    hashCode()
    iterator()
    size()
    3.3 List 特有方法
    List 作为 Collection 集合的子接口,继承了 Collection 接口中的全部方法,而且还增加
    了一些根据元素索引来操作集合的特有方法,如下:
  • public void add(int index, E element): 将指定的元素,添加到该集合中的指定位
    置上。
  • public E get(int index):返回集合中指定位置的元素。
  • public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
  • public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值
    的更新前的元素。
    List 集合特有的方法都是跟索引相关:
    public class ListDemo {
    public static void main(String[] args) {
    // 创建 List 集合对象
    List list = new ArrayList();
    // 往 尾部添加 指定元素
    list.add(“11”);
    list.add(“22”);
    list.add(“33”);
    System.out.println(list);
    // add(int index,String s) 往指定位置添加
    list.add(1,“99”);
    System.out.println(list);
    // String remove(int index) 删除指定位置元素 返回被删除元素
    // 删除索引位置为 2 的元素
    System.out.println(“删除索引位置为 2 的元素”);
    System.out.println(list.remove(2));
    System.out.println(list);
    // String set(int index,String s)
    // 在指定位置 进行 元素替代(改)
    // 修改指定位置元素
    list.set(0, “88”);
    System.out.println(list);
    // String get(int index) 获取指定位置元素
    // 跟 size() 方法一起用 来 遍历的
    for(int i = 0;i<list.size();i++){
    System.out.println(list.get(i));
    }
    //还可以使用增强 for
    for (String string : list) {
    System.out.println(string);
    }
    }
    }
    ArrayList 集合
    1.底层是数组实现的
    2.不是同步的
    3.查询比较快
    java.util.ArrayList 集合数据存储的结构是数组结构。方便元素添加、删除的集合。
    方法演示:
    public class ArrayListDemo {
    public static void main(String[] args) {
    //创建集合
    ArrayList arr = new ArrayList<>();
    //添加元素
    // public boolean add(Object Obj){};
    // arr.add(new Person(“zhansan”,18));
    // arr.add(new Person(“lisi”,19));
    // arr.add(new Person(“wangwu”,20));
    //遍历集合中的元素
    Iterator iter = arr.iterator();
    //
    while (iter.hasNext()){
    System.out.println(iter.next().getName()+iter.next().getAge());
    }
    //自动装箱
    // arr.add(8);//int,–>intger
    // arr.add(new Integer(8));
    //
    // System.out.println(arr);
    }
    }
    Person 类:
    public class Person {
    String name;
    int age;
    public Person() {
    }
    public Person(String name, int age) {
    this.name = name;
    this.age = age;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public int getAge() {
    return age;
    }
    public void setAge(int age) {
    this.age = age;
    }
    }
    源码解析:
    当第一次调用 add()方法添加元素之后,长度变为 10.
    当数组首次扩容的 10 个空间用完需要扩容后,会第二次走 grow 方法来扩容(每次扩容为
    1.5 倍)
    ArrayList 初始大小为 10,每次 1.5 倍进行扩容;它的底层是用数组实现的,所以查询速度
    相对 LinkedList 要快。
    在 jdk1.6 里面
    ArrayList 初始化大小是 10 (如果你知道你的 arrayList 会达到多少容量,可以在初始
    化的时候就指定,能节省扩容的性能开支)
    扩容点规则是,新增的时候发现容量不够用了,就去扩容
    扩容大小规则是,扩容后的大小= 原始大小+原始大小/2 + 1。(例如:原始大小是 10 ,扩
    容后的大小就是 10 + 5+1 = 16)
    在 jdk1.7 里面
    扩容大小规则是,扩容后的大小= 原始大小+原始大小/2 。(例如:原始大小是 10 ,扩容
    后的大小就是 10 + 5 = 15, 15+15/2 = 22, 22+22/2 = 33)
    LinkedList
    LinkedList 是一个继承于 AbstractSequentialList 的双向链表。它也可以被当作堆栈、
    队列或双端队列进行操作
    LinkedList 实现 List 接口,能对它进行队列操作
    由于它的底层是用双向链表实现的,所以它对元素的增加、删除效率要比ArrayList 好;它是一个双向链表,没有初始化大小,也没有扩容的机制,就是一直在前面或者后面新增就好。
    LinkedList 底层的数据结构是基于双向循环链表的,且头结点中不存放数据,如下
    Map 集合
    概述
    现实生活中,我们常会看到这样的一种集合:IP 地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射。Java 提供了专门的集合类用来存放这种对象关系的对象,即 java.util.Map 接口。
    通过查看 Map 接口描述,发现 Map 接口下的集合与 Collection 接口下的集合,它们存储数据的形式不同。
  • Collection中的集合,元素是孤立存在的(理解为单身),向集合中存储元素采用一个个元素的方式存储。
  • Map中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的值。
  • Collection中的集合称为单列集合,Map中的集合称为双列集合。
  • 需要注意的是,Map中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。
    Map 常用子类
    HashMap<K,V>:存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需要重写键的 hashCode()方法、equals()方法。
    LinkedHashMap<K,V>:HashMap 下有个子类 LinkedHashMap,存储数据采用的哈希表结构+链表结构。通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的 hashCode()方法、equals()方法。

tips:Map 接口中的集合都有两个泛型变量<K,V>,在使用时,要为两个泛型变量赋予数据
类型。两个泛型变量<K,V>的数据类型可以相同,也可以不同。
Map 接口中的常用方法
Map 接口中定义了很多方法,常用的如下:

  • public V put(K key, V value): 把指定的键与指定的值添加到 Map 集合中。
  • public V remove(Object key): 把指定的键 所对应的键值对元素 在 Map 集合中删除,返回被删除元素的值。
  • public V get(Object key) 根据指定的键,在 Map 集合中获取对应的值。
  • boolean containsKey(Object key) 判断集合中是否包含指定的键。
  • public Set<K> keySet(): 获取 Map 集合中所有的键,存储到 Set 集合中。
  • public Set<Map.Entry<K,V>> entrySet(): 获取到 Map 集合中所有的键值对对象的集
    合(Set 集合)。
    Map 接口的方法演示
    public class MapDemo {
    public static void main(String[] args) {
    //创建 map 对象
    HashMap<String, String> map = new HashMap<String, String>();
    //添加元素到集合
    map.put(“黄晓明”, “杨颖”);
    map.put(“文章”, “马伊琍”);
    map.put(“邓超”, “孙俪”);
    System.out.println(map);
    //String remove(String key)
    System.out.println(map.remove(“邓超”));
    System.out.println(map);
    // 想要查看 黄晓明的媳妇 是谁
    System.out.println(map.get(“黄晓明”));
    System.out.println(map.get(“邓超”));
    }
    }

tips:

使用 put 方法时,若指定的键(key)在集合中没有,则没有这个键对应的值,返回 null,
并把指定的键值添加到集合中;

若指定的键(key)在集合中存在,则返回值为集合中键对应的值(该值为替换前的值),并
把指定键所对应的值,替换成指定的新值。
Map 集合遍历键找值方式
键找值方式:即通过元素中的键,获取键所对应的值
分析步骤:

  1. 获取 Map 中所有的键,由于键是唯一的,所以返回一个 Set 集合存储所有的键。方法提
    示:keyset()
  2. 遍历键的 Set 集合,得到每一个键。
  3. 根据键,获取键所对应的值。方法提示:get(K key) 代码演示:
    public class DemoMap1 {
    public static void main(String[] args) {
    Map<String,String> map = new HashMap<>();
    map.put(“黄晓明”,“杨颖”);
    map.put(“邓超”,“孙俪”);
    map.put(“文章”,“马伊琍”);
    Set set = map.keySet();
    System.out.println(set);
    for (String s : set) {
    map.get(s);
    }
    }
    }
    Entry 键值对对象
    Map 中存放的是两种对象,一种称为key(键),一种称为value(值),它们在在
    Map 中是一一对应关系,这一对对象又称做 Map 中的一个 Entry(项)。Entry 将键值对的对
    应关系封装成了对象。即键值对对象,这样我们在遍历 Map 集合时,就可以从每一个键值对
    (Entry)对象中获取对应的键与对应的值。
    既然 Entry 表示了一对键和值,那么也同样提供了获取对应键和对应值得方法:
  • public K getKey():获取 Entry 对象中的键。
  • public V getValue():获取 Entry 对象中的值。
    在 Map 集合中也提供了获取所有 Entry 对象的方法:
  • public Set<Map.Entry<K,V>> entrySet(): 获取到 Map 集合中所有的键值对对象的集
    合(Set 集合)。
    Map 集合遍历键值对方式
    键值对方式:即通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值。
  1. 获取 Map 集合中,所有的键值对(Entry)对象,以 Set 集合形式返回。方法提
    示:entrySet()
  2. 遍历包含键值对(Entry)对象的 Set 集合,得到每一个键值对(Entry)对象。
  3. 通过键值对(Entry)对象,获取 Entry 对象中的键与值。 方法提示:getkey() getValue()
    public class DemoMap2 {
    public static void main(String[] args) {
    Map<String,String> map = new HashMap<>();
    map.put(“黄晓明”,“杨颖”);
    map.put(“邓超”,“孙俪”);
    map.put(“文章”,“马伊琍”);
    Set<Map.Entry<String, String>> set= map.entrySet();
    Iterator<Map.Entry<String,String>> iter = set.iterator();
    while (iter.hasNext()){
    Map.Entry<String, String> a = iter.next();
    a.getValue();
    a.getKey();
    }
    // Set<Map.Entry<String,String>> set = map.entrySet();
    //
    // Iterator<Map.Entry<String,String>>iter = set.iterator();
    // while (iter.hasNext()){
    String a = iter.next();
    // Map.Entry<String,String> entry = iter.next();
    // entry.getKey();
    // entry.getValue();
    // System.out.println(entry.getValue());
    // }
    // getKey()
    // getValue()
    // for (Map.Entry<String, String> stringStringEntry : set) {
    // System.out.println(stringStringEntry);
    // }
    }
    }

tips:Map 集合不能直接使用迭代器或者 foreach 进行遍历。但是转成 Set 之后就可以使
用了。

  • 当给 HashMap 中存放自定义对象时,如果自定义对象作为 key 存在,这时要保证对象唯一,
    必须复写对象的 hashCode 和 equals 方法(如果忘记,请回顾 HashSet 存放自定义对象)。
  • 如果要保证 map 中存放的 key 和取出的顺序一致,可以使java.util.LinkedHashMap 集合来存放。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值