集合的简述

概述

  • 一方面,面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储。另一方面,使用Array存储对象方面具有 一 些 弊 端 \textcolor{Red}{一些弊端} ,而Java集合就像一种容器,可以 动 态 地 \textcolor{Blue}{动态地} 把多个对象的引用放入容器中。
  • 数组在内存存储方面的特点:
    • 数组初始化以后,长度就确定了。
    • 数组声明的类型,就决定了进行元素初始化时的类型
  • 数组在存储数据方面的弊端:
    • 数组初始化以后,长度就不可变了,不便于扩展
    • 数组中提供的属性和方法少,不便于进行添加、删除、插入等操作,且效率不高。同时无法直接获取存储元素的个数
    • 数组存储的数据是有序的、可以重复的。---->存储数据的特点单一
  • Java集合类可以用于存储数量不等的多个 对 象 \textcolor{Red}{对象} ,还可用于保存具有映射关系的关联数组。

Java集合可分为Collection和 Map 两种体系


Collection接口方法

  1. 添加
    • a d d ( O b j e c t \textcolor{Red}{add(Object} add(Object o b j ) \textcolor{Red}{obj)} obj)
    • a d d A l l ( C o l l e c t i o n \textcolor{Red}{addAll(Collection} addAll(Collection c o l l ) \textcolor{Red}{coll)} coll)
  2. 获取有效元素的个数
    • i n t \textcolor{Red}{int} int s i z e ( ) \textcolor{Red}{size()} size()
  3. 清空集合
    • v o i d \textcolor{Red}{void} void c l e a r ( ) \textcolor{Red}{clear()} clear()
  4. 是否是空集合
    • b o o l e a n \textcolor{Red}{boolean} boolean i s E m p t y ( ) \textcolor{Red}{isEmpty()} isEmpty()
  5. 是否包含某个元素
    • b o o l e a n \textcolor{Red}{boolean} boolean c o n t a i n s ( O b j e c t \textcolor{Red}{contains(Object} contains(Object o b j ) : \textcolor{Red}{obj):} obj):是通过元素的equals方法来判断是否是同一个对象
    • b o o l e a n \textcolor{Red}{boolean} boolean c o n t a i n s A l l ( C o l l e c t i o n \textcolor{Red}{containsAll(Collection} containsAll(Collection c ) : \textcolor{Red}{c):} c):也是调用元素的equals方法来比较的。拿两个集合的元素挨个比较。
  6. 删除
    • b o o l e a n \textcolor{Red}{boolean} boolean r e m o v e ( O b j e c t \textcolor{Red}{remove(Object} remove(Object o b j ) : \textcolor{Red}{obj):} obj):通过元素的equals方法判断是否是要删除的那个元素。只会删除找到的第一个元素
    • b o o l e a n \textcolor{Red}{boolean} boolean r e m o v e A l l ( C o l l e c t i o n \textcolor{Red}{removeAll(Collection} removeAll(Collection c o l l ) : \textcolor{Red}{coll):} coll):取当前集合的差集
  7. 取两个集合的交集
    • b o o l e a n \textcolor{Red}{boolean} boolean r e t a i n A l l ( C o l l e c t i o n \textcolor{Red}{retainAll(Collection} retainAll(Collection c ) : \textcolor{Red}{c):} c):把交集的结果存在当前集合中,不影响c
  8. 集合是否相等
    • b o o l e a n \textcolor{Red}{boolean} boolean e q u a l s ( O b j e c t \textcolor{Red}{equals(Object} equals(Object o b j ) \textcolor{Red}{obj)} obj)
  9. 转成对象数组
    • O b j e c t [ \textcolor{Red}{Object[} Object[ ] \textcolor{Red}{]} ] t o A r r a y ( ) \textcolor{Red}{toArray()} toArray()
  10. 获取集合对象的哈希值
    • h a s h C o d e ( ) \textcolor{Red}{hashCode()} hashCode()
  11. 遍历
    • i t e r a t o r ( ) : \textcolor{Red}{iterator():} iterator():返回迭代器对象,用于集合遍历

使用lterator接口遍历集合元素

  • lterator对象称为迭代器(设计模式的一种),主要用于遍历Collection集合中的元素。
  • G O F 给 迭 代 器 模 式 的 定 义 为 : 提 供 一 种 方 法 访 问 一 个 容 器 ( c o n t a i n e r ) 对 象 中 各 个 元 素 , 而 又 不 需 暴 露 该 对 象 的 内 部 细 节 。 姓 代 器 模 式 , 就 是 为 容 器 而 生 。 \textcolor{Red}{GOF给迭代器模式的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。姓代器模式,就是为容器而生。} GOF:访(container)类似于“公交车上的售票员”、“火车上的乘务员”、“空姐”。
  • Collection接口继承了java.lang.lterable接口,该接口有一个iterator()方法,那么所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了lterator接口的对象。
  • l t e r a t o r 仅 用 于 遍 历 集 合 \textcolor{Blue}{lterator仅用于遍历集合} lterator,lterator木身并不提供承装对象的能力。如果需要创建lterator 对象,则必须有一个被迭代的集合。
  • 集 合 对 象 每 次 调 用 i t e r a t o r ( ) 方 法 都 得 到 一 个 全 新 的 迭 代 器 对 象 \textcolor{Blue}{集合对象每次调用iterator()方法都得到一个全新的迭代器对象} iterator(),默认游标都在集合的第一个元素之前。

注 意 : \textcolor{Red}{注意:} :

  • lterator可以删除集合的元素,但是是遍历过程中通过迭代器对象的remove方法,不是集合对象的remove方法。
  • 如 果 还 未 调 用 n e x t ( ) 或 在 上 一 次 调 用 n e x t 方 法 之 后 已 经 调 用 了 r e m o v e 方 法 , 再 调 用 r e m o v e 都 会 报 I l l e g a l S t a t e E x c e p t i o n 。 \textcolor{Red}{如果还未调用next()或在上一次调用next方法之后已经调用了remove方法,再调用remove都会报IllegalStateException。} next()nextremoveremoveIllegalStateException

使用foreach循环遍历集合元素(JDK5.0)

  • Java 5.0提供了foreach循环迭代访问Collection和数组。
  • 遍历操作不需获取collection或数;。/;‘
    ”组的长度,无需使用索引访问元素。
  • 遍 历 集 合 的 底 层 调 用 I t e r a t o r 完 成 操 作 。 \textcolor{Blue}{遍历集合的底层调用Iterator完成操作。} Iterator
  • foreach还可以用来遍历数组。
    增强for循环

面试题:ArrayList、LinkedList、Vector三者异同

同:三个类都是实现了LIst接口,存储数据的特点相同:存储有序的、可重复的数据

不同:

  • ArrayList:作为List接口的主要实现类;线程不安全,效率高;底层使用Object[ ] elementData存储
  • LinkedList:对于频繁的插入、删除操作,使用此类效率比ArrayList高;底层使用双向链表存储
  • Vector:作为List接口的古老实现类;线程是安全的,效率低;底层使用Object[ ] elementData存储

ArrayList的源码分析:

jdk7情况下

ArrayList list = new ArrayList();//底层创建了长度是10的object[ ]数组eLementData

list.add(123); //elementData[e] = new Integer(123);

list.add(11); //如果此次的添加导致底层elementData数组容量不够,则扩容。
默认情况下,扩容为原来的容量的1.5倍,同时需要将原有数组中的数据复制到新的数组中。
结 论 : \textcolor{Red}{结论:} :建议开发中使用带参的构造器: ArrayList list = new ArrayList(int capacity)

jdk8中ArrayList的变化:

ArrayList list = new ArrayList();//底层Object[ ] elementData初始化为{ },并没有创建长度为10的数组

list.add(123);//第一次调用add()时,底层才创建了长度为10的数组,并将数据123添加到elementData[0]中

后续添加和扩容操作与jdk7无异。

小结:jdk7中的ArrayList的对象的创建类似于单例的饿汉式,而jdk8中的ArrayList的对象的创建类似于单例的懒汉式,延迟了数组的创建,节省内存。

LinkedList的源码分析:

LinkedList list = new LinkedList(); 内部声明了Node类型的first和last属性,默认值为null

list.add(123); //将123封装到Node中,创建了Node对象

其中,Node定义为:体现了LinkedList的双向链表说法

private static class Node<E>{
    E item;
    Node<E> next;
    Node<E> prev;
    
    Node(Node<E> prev,E element,Node<E> next){
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

Vector的源码分析:jdk7和jdk8中通过Vector()构造器创建对象时,底层都创建了长度为10的数组。在扩容方面,默认扩容为原来数组的2倍。


代码实现:

import org.junit.Test;

import java.util.*;

/**
 * @创建人 Hexin
 * @创建时间 2022/12/1
 * @描述
 */
public class CollectionTest {
/**
 *@BelongsProject: JavaSenior
 *@BelongsPackage: PACKAGE_NAME
 *@Author: hexin
 *@CreateTime: 2022-12-01  12:47
 *@Description:
 *@Version: 1.0
 *
 */
        @Test
        public void test() {
                Collection collection = new ArrayList();
                //add(Object o):将元素e添加到集合collection中
                collection.add("AA");
                collection.add("BB");collection.add(123); //自动装箱
                collection.add(new Date());
                //size():获取添加元素的个数
                System.out.println(collection.size());//4
                //addAll():将collection1集合中的元素添加到当前集合中
                Collection collection1 = new ArrayList();

                collection1.add("CC");
                collection1.add(456789);
                collection.addAll(collection1);
                System.out.println(collection.size());//6
                System.out.println(collection);

                //clear():清空集合元素
                collection.clear();

                //isEmpty():判断当前集合是否为空
                System.out.println(collection.isEmpty());

                collection.add(new String("WLM"));
                collection.add(new Person("WLM",20));
                //contains(Object o):判断当前集合中是否包含obj
                //我们在判断时会调用obj对象所在类的equals()方法。
                //向Collection接口的实现类的对象中添加数据obj时,要求obj所在类要重写equals().
                boolean contains = collection.contains("CC");
                System.out.println(contains);
                System.out.println(collection.contains(new String("WLM"))); //比较的是内容
                System.out.println(collection.contains(new Person("WLM",20)));

                //containsAll(Collection collection1):判断collection1中的所有元素是否都存在于当前集合中。
                Collection collection2 = Arrays.asList(new Person("WLM",20),new String("WLM"));
                boolean b = collection.containsAll(collection2);
                System.out.println(b);
        }

        @Test
        public void test1() {
                Collection collection = new ArrayList();
                collection.add("AA");
                collection.add("BB");
                collection.add(123);
                collection.add(new Date());
                collection.add(new String("WLM"));
                collection.add(new Person("WLM",20));
                //remove(Object obj)
                System.out.println(collection.remove(123));

                //removeAll(Collection collection1):从当前集合中移除collection1中所有元素
                Collection collection1 = Arrays.asList(123,"AA","CXY","11223");
                collection.removeAll(collection1);
                System.out.println(collection);

                //retainAll(Collection collection1):
                collection.retainAll(collection1);
                System.out.println(collection);

                //equals(Object obj):判断当前集合和形参集合元素是否完全相等
                Collection collection2 = new ArrayList();
                collection2.addAll(collection);
                System.out.println(collection2.equals(collection));

        }
        @Test
        public void test2() {
                Collection collection = new ArrayList();
                collection.add("AA");
                collection.add("BB");
                collection.add(123);
                collection.add(new Date());
                collection.add(new String("WLM"));
                collection.add(new Person("WLM",20));

                //hashCode
                System.out.println(collection.hashCode());

                //集合 ---> 数组:toArray()
                Object array[] = collection.toArray();
                for (int i = 0; i < array.length; i++) {
                        System.out.println(array[i]);
                }

                //拓展:数组 ---> 集合:调用Arrays类静态方法asList()
                List<String> strings = Arrays.asList(new String[]{"AA", "BB", "CC"});
                System.out.println(strings);
                //数组类型转换方式一:
                List array1 = Arrays.asList(123,456);
                System.out.println(array1);
                //数组类型转换方式二:
                List array2 = Arrays.asList(new Integer[]{1,2,3,4});
                System.out.println(array2);
                System.out.println("******************");

        }
        //iterator():返回Iterator接口的实例,用于遍历集合元素。放在IteratorTest.java中测试
        @Test
        public void test3(){
                Collection collection = new ArrayList();
                collection.add("AA");
                collection.add("BB");
                collection.add(123);
                collection.add(new Date());
                collection.add(new String("WLM"));
                collection.add(new Person("WLM",20));
                Iterator iterator = collection.iterator();
                //方式一:
                System.out.println(iterator.next());
                System.out.println(iterator.next());
                System.out.println(iterator.next());
                System.out.println(iterator.next());
                System.out.println(iterator.next());
                System.out.println(iterator.next());
                System.out.println(iterator.next());
                //超出报异常
                System.out.println(iterator.next());

                //方式二:不推荐
                for (int i = 0; i < collection.size(); i++) {
                        //next():① 指针下移 ② 将下移以后集合位置上的元素返回
                        System.out.println(iterator.next());
                }

                //方式三:推荐
                //hashNext():判断是否还有下一个元素。
                while(iterator.hasNext()) {
                        System.out.println(iterator.next());
                }
        }
        @Test
        public void test4() {
                Collection collection = new ArrayList();
                collection.add("AA");
                collection.add("BB");
                collection.add(123);
                collection.add(new Date());
                collection.add(new String("WLM"));
                collection.add(new Person("WLM",20));
                //删除集合中"WLM"数据
                Iterator iterator = collection.iterator();
                while(iterator.hasNext()){
                        Object object = iterator.next();
                        if(object.equals("WLM")){
                                iterator.remove();
                        }
                }
                iterator = collection.iterator();
                while(iterator.hasNext()){
                        System.out.println(iterator.next());
                }
        }
        @Test
        public void test5() {
                Collection collection = new ArrayList();
                collection.add("AA");
                collection.add("BB");
                collection.add(123);
                collection.add(new Date());
                collection.add(new String("WLM"));
                collection.add(new Person("WLM",20));
                //for(集合元素的类型 局部变量 :集合对象)
                for(Object obj : collection){
                        System.out.println(obj);
                }
                Object array[] = collection.toArray();
                //for(数组元素的类型 局部变量 :数组对象)
                for(Object obj : array){
                        System.out.println(obj);
                }
        }
}
class Person{
        private String name;
        private int age;

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public Person() {
        }

        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;
        }

        @Override
        public String toString() {
                return "Person{" +
                        "name='" + name + '\'' +
                        ", age=" + age +
                        '}';
        }

        @Override
        public boolean equals(Object o) {
                System.out.println("Person equals()......");
                if (this == o) return true;
                if (o == null || getClass() != o.getClass()) return false;
                Person person = (Person) o;
                return age == person.age && Objects.equals(name, person.name);
        }

        @Override
        public int hashCode() {
                return Objects.hash(name, age);
        }
}

注:此文章为本人学习过程中的随手笔记,样式较为简陋,若有雷同,请见谅!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值