Java基础-集合框架1

发布于:2024-12-18 ⋅ 阅读:(58) ⋅ 点赞:(0)

集合框架

什么是集合

概念:对象的容器,定义了对多个对象进行操作的常用方法。可以实现数组的功能

和数组的区别:

  • 数组的长度固定,集合长度不固定
  • 数组可以存储基本类型和引用类型,集合只能存储引用类型

Collection体系集合

如图所示:

在这里插入图片描述

Collection:该体系结构的跟接口,代表一组对象,称为“集合”

List接口特点:有序,有下标,元素可重复

Set接口特点:无序,无下标,元素不可重复

Collection父接口

特点:代表一组任意类型的对象,无序,无下标,不能重复

方法:

  • boolean add (Object obj) // 添加一个对象

  • boolean addAll (Collection c) // 将一个集合中的所有对象添加到此集合中

  • void clear () // 清空此集合中的所有对象

  • boolean contains (Object o) // 检查此集合中是否包含o对象

  • boolean equals (Object o) // 比较此集合是否与指定对象相等

  • boolean isEmpty () // 判断此集合是否为空

  • boolean remove (Object o) // 在此集合中移除o对象

  • int size () // 返回此集合中的元素个数

  • Object [ ] toArray () // 将此集合转换成数组

    下面是保存字符串的代码验证:

    package com.collection.Demo01;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    
    public class Demo01 {
    
        public static void main(String[] args) {
    
            // 创建集合
            // 一、 保存字符串
            Collection collection = new ArrayList();
            // 1. 添加元素
            collection.add("苹果");
            collection.add("西瓜");
            collection.add("榴莲");
            System.out.println("添加之后的元素个数:" + collection.size());  // 添加之后的元素个数:3
            System.out.println(collection);  // [苹果, 西瓜, 榴莲]
            // 2. 删除元素
            // collection.remove("榴莲");
            // collection.remove("西瓜");
            // System.out.println("删除之后剩余的元素个数:"+ collection.size());  // 删除之后剩余的元素个数:1
           // 2.1 清空元素
    //        collection.clear();
    //        System.out.println("清空元素剩余:" + collection.size());  // 清空元素剩余:0
    
            // 3. 遍历元素
            // 3.1 使用增强for
            System.out.println("----------3.1 使用增强for-------------");
            for (Object obj:collection
                 ) {
                System.out.println(obj);
            }
            /*
            ----------3.1 使用增强for-------------
            苹果
            西瓜
            榴莲
             */
            // 3.2 使用迭代器(迭代器是专门用来遍历集合的一种方式)
            // hasNext(); 有没有下一个元素
            // next(); 获取下一个元素
            // remove(); 删除当前元素
            System.out.println("----------3.2 使用迭代器-------------");
            Iterator it = collection.iterator();
            while(it.hasNext()){
                String s = (String)it.next();
                System.out.println(s);
                // 不能使用collection删除方法
                // collection.remove(s);  // ConcurrentModificationException   并发修改异常
                // it.remove();     // 迭代器提供的方法
            }
            System.out.println("剩余的元素个数: "+ collection.size());
            /*
            ----------3.2 使用迭代器-------------
            苹果
            西瓜
            榴莲
            剩余的元素个数: 3
             */
            // 4. 判断
            System.out.println(collection.contains("xigua"));  // false
            System.out.println(collection.contains("西瓜"));  // true
            System.out.println(collection.isEmpty());  // false     判断是否为空// null空 为 true ; not null非空 为 false
    
        }
    
    
    }
    

下面是保存学生信息的代码实现:

学生类 Student:

package com.collection.Demo01;

/**
 * 学生类
 */
public class Student {
    private String name ;
    private int age ;

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

    public Student() {

    }

    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 "学生信息:[name=" + name + ",age="+age + "]";
    }

    @Override	// 重写方法
    public boolean equals(Object obj) {
        // 1 判断是不是同一个对象
        if (this==obj){
            return true;
        }
        // 2 判断是否为空
        if (obj==null){
            return false;
        }
        // 3 判断是否是Student类型
        if(obj instanceof Student){
            Student s = (Student) obj;
            // 4 比较属性
            if (this.name.equals(s.getName())&&this.age==s.getAge()){
                return true;
            }
        }
        // 5 不满足条件返回false
        return false;
    }
}

代码验证:

package com.collection.Demo01;

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

public class Demo02 {
    public static void main(String[] args) {
        // 新建 Collection 对象
        Collection collection = new ArrayList();
        Student s1 = new Student("张三",18);
        Student s2 = new Student("李四",17);
        Student s3 = new Student("王五",19);
        // 1. 添加数据
        collection.add(s1);
        collection.add(s2);
        collection.add(s3);
        System.out.println("元素个数:" + collection.size());  // 元素个数:3
        System.out.println(collection);  // [学生信息:[name=张三,age=18], 学生信息:[name=李四,age=17], 学生信息:[name=王五,age=19]]
        // 2. 删除数据
        // collection.remove(s2);
        // collection.remove(new Student("王五",19));  // 并没有删除
        // collection.clear();
        // System.out.println("删除之后的剩余元素:" + collection.size());  // 删除之后的剩余元素:0    // 只是删掉了地址


        // 3. 遍历

        // 3.1 增强for
        System.out.println("--------增强for------");
        for (Object obj:collection) {
                Student s = (Student) obj;
            System.out.println(s.toString());
        }
        /*
        --------增强for------
        学生信息:[name=张三,age=18]
        学生信息:[name=李四,age=17]
        学生信息:[name=王五,age=19]
         */

        // 3.2 迭代器
        // hasNext();   next();   remove();     迭代过程中不能使用collection的删除方法
        System.out.println("--------迭代器------");
        Iterator it = collection.iterator();
        while (it.hasNext()){
            Student s = (Student)it.next();
            System.out.println(s);
        }
        /*
        --------迭代器------
        学生信息:[name=张三,age=18]
        学生信息:[name=李四,age=17]
        学生信息:[name=王五,age=19]
         */

        // 4. 判断
        System.out.println(collection.contains(s1));  // true
        System.out.println(collection.isEmpty());  // false

    }
}

List子接口

特点:有序,有下标,元素可以重复

方法:

  • void add (int index,Object o) // 在index位置插入对象
  • boolean addAll (int index,Collection c) 将一个集合中的元素添加到此集合中的index 位置
  • Object get (int index) // 返回集合中指定位置的元素
  • List subList (int fromIndex,int toIndex) // 返回fromIndex和toIndex之间的集合元素

下面是字符串案例:

package com.collection.list;

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

public class Demo01 {
    public static void main(String[] args) {
        // 先创建集合对象
        List list = new ArrayList();
        // 1. 添加元素

        list.add("小米");
        list.add("华为");
        list.add(0,"苹果");
        System.out.println("元素个数:" + list.size());  // 元素个数:3
        System.out.println(list.toString());  // [苹果, 小米, 华为]
        // 2. 删除元素
        // list.remove("华为");
        // list.remove(1);
        // System.out.println("删除之后还剩余:" + list.size());  // 删除之后还剩余:1
        // System.out.println(list);  // [苹果]
        // 3. 遍历
        // 3.1 使用for遍历
        System.out.println("--------使用for遍历--------");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        /*
        --------使用for遍历--------
        苹果
        小米
        华为
         */
        // 3.2 使用增强for
        System.out.println("--------使用增强for--------");
        for (Object obj:list
             ) {
            System.out.println(obj);
        }
        /*
        --------使用增强for--------
        苹果
        小米
        华为
         */
        // 3.3 使用迭代器
        Iterator it = list.iterator();
        System.out.println("--------使用迭代器--------");
        while (it.hasNext()){
            System.out.println(it.next());
        }
        /*
        --------使用迭代器--------
        苹果
        小米
        华为
         */
        // 3.4 使用列表迭代器,和Iterator的区别: ListIterator可以向前或者向后遍历,添加,删除,修改元素
        ListIterator lit = list.listIterator();
        System.out.println("--------使用列表迭代器==从前往后--------");
        while(lit.hasNext()){
            System.out.println(lit.nextIndex()+":" +lit.next());
        }
        /*
        --------使用列表迭代器==从前往后--------
        0:苹果
        1:小米
        2:华为
         */
        System.out.println("--------使用列表迭代器==从后往前--------");
        while (lit.hasPrevious()){
            System.out.println(lit.previousIndex()+": "+lit.previous());
        }
        /*
        2: 华为
        1: 小米
        0: 苹果
         */
        // 4. 判断
        System.out.println(list.contains("苹果"));  // true
        System.out.println(list.isEmpty());  // false
        // 5.获取位置
        System.out.println(list.indexOf("苹果"));  // 0
        System.out.println(list.indexOf("华为"));  // 2
    }
}

下面是数字,基本类型(自动装箱):

package com.collection.list;

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

public class Demo02 {
    public static void main(String[] args) {
        // 创建集合
        List list = new ArrayList();
        // 1. 添加数字数据(自动装箱)
        list.add(10);
        list.add(20);
        list.add(30);
        list.add(40);
        list.add(50);
        System.out.println("元素个数:"+list.size());  // 元素个数:5
        System.out.println(list);  // [10, 20, 30, 40, 50]
        // 2. 删除操作
        // list.remove(2);
        // list.remove(new Integer(20));
        // list.remove((Object) 40);
        // System.out.println("删除元素:" + list.size());  // 删除元素:2
        // System.out.println(list);  // [10, 50]
        // 3. 补充方法:subList  返回子集合,左闭右开区间  [ )
        List subList = list.subList(1,4);
        System.out.println(subList);  // [20, 30, 40]


    }
}

下面是学生信息:

学生类同上:

package com.collection.list;

import com.collection.Demo01.Student;

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

public class Demo03 {
    public static void main(String[] args) {
        // 创建集合
        ArrayList arrayList = new ArrayList();
        // 1. 添加元素
        Student s1 = new Student("源氏",18);
        Student s2 = new Student("艾什",18);
        Student s3 = new Student("狂鼠",19);
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        System.out.println("元素个数:"+arrayList.size());  // 元素个数:3
        System.out.println(arrayList);  // [学生信息:[name=源氏,age=18], 学生信息:[name=艾什,age=18], 学生信息:[name=狂鼠,age=19]]
        // 2. 删除元素
        // arrayList.remove(new Student("狂鼠",19));  // equals(this==obj)
        // arrayList.remove(s2);
        // System.out.println("删除之后:" + arrayList.size());  // 删除之后:1
        // System.out.println(arrayList);  // [学生信息:[name=源氏,age=18]]
        // 3. 遍历元素  ⭐
        // 使用迭代器
        System.out.println("----------使用迭代器----------");
        Iterator it = arrayList.iterator();
        while (it.hasNext()){
            Student s = (Student) it.next();
            System.out.println(s.toString());
        }
        /*
        ----------使用迭代器----------
        学生信息:[name=源氏,age=18]
        学生信息:[name=艾什,age=18]
        学生信息:[name=狂鼠,age=19]
         */
        // 使用列表迭代器
        ListIterator lit = arrayList.listIterator();
        System.out.println("----------使用列表迭代器==顺序----------");
        while (lit.hasNext()){
            Student s = (Student) lit.next();
            System.out.println(s.toString());
        }
        /*
        ----------使用列表迭代器==顺序----------
        学生信息:[name=源氏,age=18]
        学生信息:[name=艾什,age=18]
        学生信息:[name=狂鼠,age=19]
         */
        System.out.println("----------使用列表迭代器==逆序----------");
        while (lit.hasPrevious()){
            Student s = (Student) lit.previous();
            System.out.println(s.toString());
        }
        /*
        ----------使用列表迭代器==逆序----------
        学生信息:[name=狂鼠,age=19]
        学生信息:[name=艾什,age=18]
        学生信息:[name=源氏,age=18]
         */
        // 4. 判断
        System.out.println(arrayList.contains(new Student("狂鼠",19)));  // true
        System.out.println(arrayList.contains(s2));  // true
        System.out.println(arrayList.isEmpty());  // false
        // 5. 查找
        System.out.println(arrayList.indexOf(new Student("狂鼠",19)));  // 2
        System.out.println(arrayList.indexOf(new Student("源氏",19)));  // -1  // 年龄应为18 ,没有查找到返回-1



    }
}

List 实现类

  • ArrayList [重点]:

    数组结构实现,查询快,增删慢

    JDK1.2版本,运行效率快,线程不安全

  • Vector:

    数组结构实现,查询快,增删慢

    JDK1.0版本,运行效率慢,线程安全

  • LinkedList:

    链表结构实现,增删快,查询慢

ArrayList

源码分析:

DEFAULT_CAPACITY = 10 ; 默认容量

​ 注意:如果没有向集合中添加任何元素时,容量为0;

​ 添加一个元素之后,容量为10;

​ 每次扩容的大小是原来的1.5倍

elementDate 存放元素的数组

size 实际元素个数

add () 添加元素

Vector

Vector简介

Vector 是矢量队列,它是JDK1.0版本添加的类。继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口。
Vector 继承了AbstractList,实现了List;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能
Vector 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在Vector中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。
Vector 实现了Cloneable接口,即实现clone()函数。它能被克隆。

和ArrayList不同,Vector中的操作是线程安全的

(01) Vector实际上是通过一个数组去保存数据的。当我们构造Vecotr时;若使用默认构造函数,则Vector的默认容量大小是10
(02) 当Vector容量不足以容纳全部元素时,Vector的容量会增加。若容量增加系数 >0,则将容量的值增加“容量增加系数”;否则,将容量大小增加一倍。
(03) Vector的克隆函数,即是将全部元素克隆到一个数组中。

package com.collection.vector;

import java.util.Enumeration;
import java.util.Vector;

public class Demo01 {

    public static void main(String[] args) {
        // 创建集合
        Vector vector = new Vector();
        // 1. 添加元素
        vector.add("苹果");
        vector.add("草莓");
        vector.add("葡萄");
        System.out.println("元素个数:"+vector.size());  // 元素个数:3
        System.out.println(vector);  // [苹果, 草莓, 葡萄]
        // 2. 删除元素
        // vector.remove(0);
        // vector.remove("葡萄");
        // vector.clear();
        // System.out.println("元素个数:" + vector.size());  // 元素个数:0
        // 3. 遍历
        // 使用枚举器
        Enumeration en = vector.elements();
        while (en.hasMoreElements()){
            String str = (String)en.nextElement();
            System.out.println(str);
        }
        /*
        苹果
        草莓
        葡萄
         */
        // 4. 判断
        System.out.println(vector.contains("葡萄"));  // true
        System.out.println(vector.isEmpty());  // false
        // 5. 其他方法
        System.out.println(vector.firstElement());  // 苹果
        System.out.println(vector.lastElement());  // 葡萄
        System.out.println(vector.elementAt(1));  // 草莓
    }
}

LinkedList

LinkedList官方文档
LinkedList的底层是双向链表结构,由于链表没有将元素存储在连续的空间中,而是存储在单独的节点中,然后通过引用将节点连接起来了,因此在任意位置插入或者删除元素时,不需要搬移元素,效率比较高。

注意:

LinkedList实现了List接口
LinkedList的底层使用了双向链表
LinkedList没有实现RandomAccess接口,因此LinkedList不支持随机访问
LinkedList的任意位置插入和删除元素时效率比较高,时间复杂度为O(1)
LinkedList比较适合任意位置插入的场景

package com.collection.vector;

import java.util.Enumeration;
import java.util.Vector;

public class Demo01 {

    public static void main(String[] args) {
        // 创建集合
        Vector vector = new Vector();
        // 1. 添加元素
        vector.add("苹果");
        vector.add("草莓");
        vector.add("葡萄");
        System.out.println("元素个数:"+vector.size());  // 元素个数:3
        System.out.println(vector);  // [苹果, 草莓, 葡萄]
        // 2. 删除元素
        // vector.remove(0);
        // vector.remove("葡萄");
        // vector.clear();
        // System.out.println("元素个数:" + vector.size());  // 元素个数:0
        // 3. 遍历
        // 使用枚举器
        Enumeration en = vector.elements();
        while (en.hasMoreElements()){
            String str = (String)en.nextElement();
            System.out.println(str);
        }
        /*
        苹果
        草莓
        葡萄
         */
        // 4. 判断
        System.out.println(vector.contains("葡萄"));  // true
        System.out.println(vector.isEmpty());  // false
        // 5. 其他方法
        System.out.println(vector.firstElement());  // 苹果
        System.out.println(vector.lastElement());  // 葡萄
        System.out.println(vector.elementAt(1));  // 草莓
    }
}

ArrayList和LinkedList的区别
ArrayList的物理存储空间是连续的,LinkedList物理上不一定连续。
ArrayList支持随机访问,LinkedList不支持随机访问。
ArrayList在插入和删除的时候时间复杂度O(N),LinkedList时间复杂度O(1);所以LinkedList适合频繁插入和删除的场景。
ArrayList空间不够需要动态扩容,LinkedList不需要。

泛型

Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递

常见形式有:泛型类、泛型接口、泛型方法

语法: T 称为类型占位符,表示一种引用类型

好处:1 提高代码的重(chong)用性

​ 2 防止类型转换异常,提高代码的安全性

下面是泛型类:

package com.collection.generic;

public class Generic<T> {
    // 泛型类:Generic<T>
    // 语法: 类名<T>
    // T是类型占位符,表示一种引用类型,如果编写多个使用逗号隔开

    // 使用泛型 T
    // 1. 创建变量
    // 泛型不能实例化
    T t ;

    // 2. 泛型作为方法的参数
    public void show(T t){
        System.out.println("泛型作为方法的参数:" + t);
    }

    // 3. 泛型作为方法的返回值
    public T getT(){
        // return (T)("泛型作为方法的返回值" + t);
         return t;
    }
}

下面是泛型方法:

package com.collection.generic;


/**
 *
 * 泛型方法
 * 语法:<T>返回值类型
 *
 */
public class GenericMethod {
    // 泛型方法
    public <T> T show(T t){
        System.out.println("泛型方法 "+ t);
        return t;
    }
}

下面是泛型接口:

接口
package com.collection.generic;

/**
 * 泛型接口
 * 语法:接口名<T>
 * 注意:不能创建静态常量
 * @param <T>
 */
public interface GenericService<T> {
    String name = "张三";

    T server(T t);
}
package com.collection.generic;

public class GenericServiceImpl implements GenericService<String>{

    @Override
    public String server(String t) {
        System.out.println(t);
        return t;
    }
}
package com.collection.generic;

public class GenericServiceImpl2<T> implements GenericService<T>{

    @Override
    public T server(T t) {
        System.out.println(t);
        return t;
    }
}

泛型测试:

package com.collection.generic;

public class TestGeneric {
    public static void main(String[] args) {
        // 使用泛型类创建对象
        /*
        注意:
        1. 泛型只能使用引用类型
        2. 不同泛型类型对象之间不能相互赋值
         */
        Generic<String> generic = new Generic<String>();
        generic.t = "Java";
        generic.show("我爱学习Java,大家加油!");  // 泛型作为方法的参数:我爱学习Java,大家加油!
        String string = generic.getT();
        System.out.println(string);  // Java

        Generic<Integer> generic1 = new Generic<>();
        generic1.t = 18;
        generic1.show(180);  // 泛型作为方法的参数:180
        Integer integer = generic1.getT();
        System.out.println(integer);  // 18

        // 泛型接口
        GenericService gs = new GenericServiceImpl();
        gs.server("java");  // java

        GenericService gs2 = new GenericServiceImpl2();
        gs2.server(10086);  // 10086

        // 泛型方法
        GenericMethod gm = new GenericMethod();
        gm.show("java is best!");  // 泛型方法 java is best!
        gm.show(10086);  // 泛型方法 10086
        gm.show(3.1415926);  // 泛型方法 3.1415926

    }
}

泛型集合

概念:参数化类型、类型安全的集合、强制集合元素的类型必须一致

特点:

  • 编译时即可检查,而非运营时抛出异常
  • 访问时,不必类型转换(拆箱)
  • 不同泛型之间引用不能相互赋值,泛型不存在多态

网站公告

今日签到

点亮在社区的每一天
去签到