day20_java集合之Collection接口

Java 集合框架概述

一方面, 面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象 的操作,就要对对象进行存储。另一方面,使用Array存储对象方面具有一些弊 ,而Java 集合就像一种容器,可以动态地把多个对象的引用放入容器中。

数组在内存存储方面的特点:

  • 数组初始化以后,长度就确定了。
  • 数组声明的类型,就决定了进行元素初始化时的类型

数组在存储数据方面的弊端:

  • 数组初始化以后,长度就不可变了,不便于扩展
  • 数组中提供的属性和方法少,不便于进行添加、删除、插入等操作,且效率不高。
  • 同时无法直接获取存储元素的个数
  • 数组存储的数据是有序的、可以重复的。---->存储数据的特点单一

Java 集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的 关联数组。

集合和数组的区别

  • 数组的长度是固定的。集合的长度是可变的。
  • 数组中存储的是同一类型的元素,可以存储基本数据类型值。集合存储的都是对象。而且对象的类型可以不一致。在开发中一般当对象多的时候,使用集合进行存储。

学习集合的目标

  • 会使用集合存储数据
  • 会遍历集合,把数据取出来
  • 掌握每种集合的特性

学习集合的方式

  • 学习顶层:学习顶层的接口/抽象类共性的方法,所有的子类都可以使用
  • 使用底层:顶层不是抽象类就是接口,无法创建对象使用。我们要使用底层的实现类来创建对象使用。‘
Java 集合可分为 Collection Map 两种体系
  • Collection接口:单列数据,定义了存取一组对象的方法的集合 List元素有序、可重复的集合 Set元素无序、不可重复的集合
  • Map接口:双列数据,保存具有映射关系“key-value对”的集合

Collection接口继承树

           

Map接口继承树

                                

Collection 接口

  • Collection 接口是 ListSet Queue 接口的父接口,该接口里定义的方法 既可用于操作 Set 集合,也可用于操作 List Queue 集合。
  • JDK不提供此接口的任何直接实现,而是提供更具体的子接口(如:SetList) 实现。
  • Java5 之前,Java 集合会丢失容器中所有对象的数据类型,把所有对象都 当成 Object 类型处理;从 JDK 5.0 增加了泛型以后,Java 集合可以记住容 器中对象的数据类型。

Collection 接口方法

1、添加

  • add(Object obj)
  • addAll(Collection coll)

2、获取有效元素的个数

  • int size()

3、清空集合

  • void clear()

4、是否是空集合

  • boolean isEmpty()

举例:

package CollenctionTest;

import org.junit.Test;

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

public class Demo01Collection {
    @Test
    public void methodTest() {
        //多态
        Collection coll = new ArrayList();

        //add(Object e):将元素e添加到集合coll中
        coll.add("AA");
        coll.add("BB");
        coll.add(123);//自动装箱
        coll.add(new Date());

        //size():获取添加的元素的个数
        System.out.println(coll.size());//4

        //addAll(Collection coll1):将参数集合中的元素添加到当前的集合中
        Collection coll1 = new ArrayList();
        coll1.add(456);
        coll1.add("CC");
        coll.addAll(coll1);

        System.out.println(coll.size());//6
        System.out.println(coll);//[AA, BB, 123, Fri Mar 13 02:44:35 CST 2020, 456, CC]

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

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

    }
}

5、是否包含某个元素

  • boolean contains(Object obj)是通过元素的equals方法来判断是否 是同一个对象
  • boolean containsAll(Collection c)也是调用元素的equals方法来比较的。拿两个集合的元素挨个比较

6、删除

  • boolean remove(Object obj) 通过元素的equals方法判断是否是 要删除的那个元素。只会删除找到的第一个元素
  • boolean removeAll(Collection coll)取当前集合的差集

举例:

 @Test
    public void methodTest1() {
        Collection coll = new ArrayList();
        /*
        1.contains(Object obj):判断当前集合中是否包含obj
        我们在判断时会调用obj对象所在类的equals()。
        向Collection接口的实现类的对象中添加数据obj时,要求obj所在类要重写equals().
         */
        coll.add(1);
        coll.add(new String("a"));
        coll.add(123);
        System.out.println(coll.contains("a"));//true
        
        //2.containsAll(Collection coll1):判断形参coll1中的所有元素是否都存在于当前集合中。
        Collection coll1 = Arrays.asList(123, 4567);
        System.out.println(coll.containsAll(coll1));//false
        
        //3.remove(Object obj):从当前集合中移除obj元素。
        boolean a = coll.remove("a");
        System.out.println(coll);//[1, 123]
        
        //4. removeAll(Collection coll1):差集:从当前集合中移除coll1中所有的元素。
        coll.removeAll(coll1);
        System.out.println(coll);//[1]

    }

7、取两个集合的交集

  •  boolean retainAll(Collection c)把交集的结果存在当前集合中,不影响c

8、集合是否相等

  • boolean equals(Object obj)

举例:

 @Test
    public void Test2() {
        Collection c1 = new ArrayList();
        c1.add(123);
        c1.add(456);
        c1.add(new String("Tom"));
        c1.add(false);

        //5.retainAll(Collection coll1):交集:获取当前集合和coll1集合的交集,并返回给当前集合
        Collection c2 = Arrays.asList(123, 456);
        c1.retainAll(c2);
        System.out.println(c1);//[123, 456]

        //6.equals(Object obj):要想返回true,需要当前集合和形参集合的元素都相同。
        System.out.println(c1.equals(c2));//true
    }

9、转成对象数组

  • Object[] toArray()

10、获取集合对象的哈希值

  • hashCode()

11、遍历

  •  iterator()返回迭代器对象,用于集合遍历

​​​​​​​举例:

 @Test
    public void test3() {
        Collection coll = new ArrayList();
        //添加元素
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(false);

        //7.hashCode():返回当前对象的哈希值
        System.out.println(coll.hashCode());

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

        //拓展:数组 --->集合:调用Arrays类的静态方法asList()
        List<String> list = Arrays.asList(new String[]{"AA", "BB", "CC"});
        System.out.println(list);

        List arr1 = Arrays.asList(new int[]{123, 456});
        System.out.println(arr1.size());//1

        List arr2 = Arrays.asList(new Integer[]{123, 456});
        System.out.println(arr2.size());//2

        //9.iterator():返回Iterator接口的实例,用于遍历集合元素。放在IteratorTest.java中测试
    }

使用 Iterator 接口遍历集合元素

  • Iterator对象称为迭代器(设计模式的一种),主要用于遍历 Collection 集合中的元素。
  • GOF给迭代器模式的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。迭代器模式,就是为容器而生。​​​​​​​
  • Collection接口继承了java.lang.Iterable接口,该接口有一个iterator()方法,那么所 有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了 Iterator接口的对象。
  • Iterator 仅用于遍历集合Iterator 本身并不提供承装对象的能力。如果需要创建 Iterator 对象,则必须有一个被迭代的集合。
  • 集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合 的第一个元素之前。

下面介绍一下获取迭代器的方法:

  • public Iterator iterator() : 获取集合对应的迭代器,用来遍历集合中的元素的。

下面介绍一下迭代的概念:

  • 迭代:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。

Iterator接口的常用方法如下:

  • public E next() :返回迭代的下一个元素。
  • public boolean hasNext() :如果仍有元素可以迭代,则返回 true。

迭代器的使用步骤(重点):

  1. 使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态)
  2. 使用Iterator接口中的方法hasNext判断还有没有下一个元素
  3. 使用Iterator接口中的方法next取出集合中的下一个元素

接下来我们通过案例学习如何使用Iterator迭代集合中元素:

package demo02;


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

/*
    java.util.Iterator接口:迭代器(对集合进行遍历)
    有两个常用的方法
        boolean hasNext() 如果仍有元素可以迭代,则返回 true。
            判断集合中还有没有下一个元素,有就返回true,没有就返回false
        E next() 返回迭代的下一个元素。
            取出集合中的下一个元素
    Iterator迭代器,是一个接口,我们无法直接使用,需要使用Iterator接口的实现类对象,获取实现类的方式比较特殊
    Collection接口中有一个方法,叫iterator(),这个方法返回的就是迭代器的实现类对象
        Iterator<E> iterator() 返回在此 collection 的元素上进行迭代的迭代器。

    迭代器的使用步骤(重点):
        1.使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态)
        2.使用Iterator接口中的方法hasNext判断还有没有下一个元素
        3.使用Iterator接口中的方法next取出集合中的下一个元素
 */
public class Demo01Iterator {
    public static void main(String[] args) {
        //创建一个集合对象
        Collection<String> coll = new ArrayList<>();
        //往集合中添加元素
        coll.add("姚明");
        coll.add("科比");
        coll.add("麦迪");
        coll.add("詹姆斯");
        coll.add("艾弗森");

        /*
            1.使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态)
            注意:
                Iterator<E>接口也是有泛型的,迭代器的泛型跟着集合走,集合是什么泛型,迭代器就是什么泛型
         */
        //多态  接口            实现类对象
        Iterator<String> it = coll.iterator();

        //2.使用Iterator接口中的方法hasNext判断还有没有下一个元素
        while(it.hasNext()){
            //3.使用Iterator接口中的方法next取出集合中的下一个元素
            String e = it.next();
            System.out.println(e);
        }
        System.out.println("----------------------");
        //for循环的格式 遍历元素
        for(Iterator<String> it2 = coll.iterator();it2.hasNext();){
            String e = it2.next();
            System.out.println(e);
        }


    }
}

注意:

  • 在进行集合元素取出时,如果集合中已经没有元素了,还继续使用迭代器的next方法,将会发生java.util.NoSuchElementException没有集合元素的错误。

迭代器的实现原理

我们在之前案例已经完成了Iterator遍历集合的整个过程。当遍历集合时,首先通过调用t集合的iterator()方法获得迭代器对象,然后使用hashNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出,否则说明已到达了集合末尾,停止遍历元素。Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素,为了让初学者能更好地理解迭代器的工作原理,接下来通过一个图例来演示Iterator对象迭代元素的过程:

                     

在调用Iterator的next方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的next方法后,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用next方法时,迭代器的索引会指向第二个元素并将该元素返回,依此类推,直到hasNext方法返回false,表示到达了集合的末尾,终止对元素的遍历。

 注意:

  •  Iterator可以删除集合的元素,但是是遍历过程中通过迭代器对象的remove方法,不是集合对象的remove方法。
  • 如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法, 再调用remove都会报IllegalStateException

 举例:

package CollenctionTest;

package com.atguigu.java;

import org.junit.Test;

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

/**
 * 集合元素的遍历操作,使用迭代器Iterator接口
 * 1.内部的方法:hasNext() 和  next()
 * 2.集合对象每次调用iterator()方法都得到一个全新的迭代器对象,
 * 默认游标都在集合的第一个元素之前。
 * 3.内部定义了remove(),可以在遍历的时候,删除集合中的元素。此方法不同于集合直接调用remove()
 *

 */
public class IteratorTest {

    //测试Iterator中的remove()
    //如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法,
    // 再调用remove都会报IllegalStateException。
    @Test
    public void test3() {
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(false);

        //删除集合中"Tom"
        Iterator iterator = coll.iterator();
        while (iterator.hasNext()) {
            //  iterator.remove(); 错误
            Object obj = iterator.next();
            if ("Tom".equals(obj)) {
                iterator.remove();
                // iterator.remove();错误
            }

        }
        //遍历集合,集合对象每次调用iterator()方法都得到一个全新的迭代器对象,
        iterator = coll.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

使用 foreach 循环遍历集合元素

  • Java 5.0 提供了 foreach 循环迭代访问 Collection和数组。
  • 遍历操作不需获取Collection或数组的长度,无需使用索引访问元素。
  • 遍历集合的底层调用Iterator完成操作。
  • foreach还可以用来遍历数组。​​​​​​​
  • public interface Iterable<T>实现这个接口允许对象成为 "foreach" 语句的目标。Collection<E>extends Iterable<E>:所有的单列集合都可以使用增强for

格式:

它用于遍历Collection和数组。通常只进行遍历元素,不要在遍历的过程中对集合元素进行增删操作

代码举例

package CollenctionTest;



import org.junit.Test;

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

public class ForTest {

    @Test
    public void test1() {
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(false);

        //for(集合元素的类型 局部变量 : 集合对象)
        //内部仍然调用了迭代器。
        for (Object obj : coll) {
            System.out.println(obj);
        }
    }

    @Test
    public void test2() {
        int[] arr = new int[]{1, 2, 3, 4, 5, 6};
        //for(数组元素的类型 局部变量 : 数组对象)
        for (int i : arr) {
            System.out.println(i);
        }
    }

    //练习题
    @Test
    public void test3() {

        String[] arr1 = new String[]{"MM"};

        //方式一:普通for赋值
        for (int i = 0; i < arr1.length; i++) {
            arr1[i] = "GG";
        }

        for (int i = 0; i < arr1.length; i++) {
            System.out.println(arr1[i]);//GG
        }
        String[] arr2 = new String[]{"MM"};
        //方式二:增强for循环
        for (String s : arr2) {
            s = "GG";
        }

        for (int i = 0; i < arr2.length; i++) {
            System.out.println(arr2[i]);//MM
        }


    }
}
发布了0 篇原创文章 · 获赞 7 · 访问量 6337

猜你喜欢

转载自blog.csdn.net/weixin_44462792/article/details/104810515
今日推荐