Java集合框架

Java集合框架

集合就是一个容器,可以存储很多东西,可添加、删除、修改。

Collection接口

Collection接口是Java集合的根接口,是所有集合的父接口,该接口提供了许多操作集合抽象方法。

jdk对于Collection接口不提供直接的实现类
Java源码Collection接口

其中最常用的主要有两个子接口:set接口、list接口
set接口
在这里插入图片描述
list接口
在这里插入图片描述

此接口的实现类有(非直接的实现类):
在这里插入图片描述
在这里插入图片描述

Collection接口提供的抽象方法

boolean add(E e) 
确保此集合包含指定的元素(只添加一个元素)。  
boolean addAll(Collection<? extends E> c) 
将指定集合中的所有元素添加到这个集合(添加多个元素)。  
void clear() 
从这个集合中移除所有的元素(删除集合中的所有元素)。  
boolean contains(Object o) 
返回 true如果集合包含指定元素。  
boolean containsAll(Collection<?> c) 
返回 true如果这个集合包含指定集合的所有元素。  
boolean equals(Object o) 
将指定的对象与此集合进行比较,以进行相等性。  
int hashCode() 
返回此集合的哈希代码值。  
boolean isEmpty() 
返回 true如果集合不包含任何元素。  
Iterator<E> iterator() 
返回此集合中的元素的迭代器。  
default Stream<E> parallelStream() 
返回一个可能并行 Stream与集合的来源。  
boolean remove(Object o) 
从这个集合中移除指定元素的一个实例,如果它是存在的(删除一个元素)。  
boolean removeAll(Collection<?> c) 
删除此集合中包含的所有元素(可选操作)的所有元素(可选操作)。  
default boolean removeIf(Predicate<? super E> filter) 
删除满足给定谓词的这个集合的所有元素。  
boolean retainAll(Collection<?> c) 
仅保留包含在指定集合中的这个集合中的元素(可选操作)。  
int size() 
返回此集合中的元素的数目。  
default Spliterator<E> spliterator() 
创建此集合中的元素的 Spliterator。  
default Stream<E> stream() 
返回一个序列 Stream与集合的来源。  
Object[] toArray() 
返回包含此集合中所有元素的数组。  
<T> T[] toArray(T[] a) 
返回包含此集合中所有元素的数组;返回数组的运行时类型是指定的数组的运行时类型。  

Collection接口中的一些基本方法测试

package com.tedu.cn;

import org.junit.Test;

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

public class Demo1 {
    @Test
    public void m1(){
        System.out.println("测试junit环境是否可行");
    }

    /**
     * 测试Collection接口提供的操作集合的方法
     *add方法
     * 对于这个测试方法,掌握创建集合对象、向集合里面添加元素、遍历集合
     */

    @Test
    public void m2(){
        /**
         * 创建一个集合对象,把子类的对象赋值给父类使用,该对象称为上转型对象
         */
        Collection collection=new ArrayList();
        /**
         * 添加元素之前调用size方法查看集合的元素个数
         */
        System.out.println("添加元素前集合的长度是:"+collection.size());
        /**
         * 向集合里面添加元素,如果成功返回true,失败返回false
         */
        collection.add("语文");
        collection.add("数学");
        collection.add("英语");
        collection.add("物理");
        System.out.println("添加元素后集合的长度是:"+collection.size());
        /**
         * 遍历集合
         */
        for (Object ob:collection) {
            System.out.println("当前遍历的元素是:"+ob);
        }
    }

    /**
     * 测试向集合里批量添加元素
     * addAll方法
     */
    @Test
    public void m3(){
        Collection c1=new ArrayList();
        Collection c2=new ArrayList();
        c1.add("语文");
        c1.add("数学");
        c2.add("英语");
        c2.add("物理");
        System.out.println("添加c1前集合的长度"+c2.size());
        /**
         * 使用addAll将一个集合里的所有元素加至另一集合
         */
        c2.addAll(c1);
        System.out.println("添加c1后集合的长度"+c2.size());
    }

    /**
     * 删除集合里的一个元素
     * remove方法
     */
    @Test
    public void m4(){
        Collection c1=new ArrayList();
        c1.add("语文");
        c1.add("数学");
        System.out.println("删除前集合的长度是:"+c1.size());
        c1.remove("语文");
        System.out.println("删除后集合的长度是:"+c1.size());
    }

    /**
     * 清除集合中的所有元素
     * clear方法
     */
    @Test
    public void m5(){
        Collection c1=new ArrayList();
        c1.add("语文");
        c1.add("数学");
        System.out.println("清除前集合的长度是:"+c1.size());
        c1.clear();
        System.out.println("清除后集合的长度是:"+c1.size());
    }
    /**
     * 批量从集合里面移除元素
     */
    @Test
    public void m7(){
        Collection c1=new ArrayList();
        Collection c2=new ArrayList();
        c1.add("语文");
        c1.add("数学");
        c2.add("语文");
        c2.add("数学");
        c2.add("英语");
        c2.add("物理");
        boolean f=c2.removeAll(c1);
        if(f){
            System.out.println("批量移除元素成功");
        }
        for(Object o:c2){
            System.out.println("当前遍历元素是:"+o);
        }
    }

    /**
     * 使用迭代器遍历集合
     */
    @Test
    public void m8(){
        /**
         * 获取迭代器的方法,可通过集合对象名.iterator
         */
        Collection c1=new ArrayList();
        c1.add("语文");
        c1.add("数学");
        //获取c1集合的迭代器
        Iterator iterator=c1.iterator();
        //使用迭代器遍历集合
        while (iterator.hasNext()){
            System.out.println("当前迭代的对象是:"+iterator.next());
        }
    }

    /**
     *集合转换为数组
     */
    @Test
    public void m9(){
        Collection c1=new ArrayList();
        c1.add("语文");
        c1.add("数学");
        Object[] obs=c1.toArray();
        System.out.println(Arrays.toString(obs));
    }
}

Set集合

Set集合的特点:无序不可重复集(集合的元素的顺序是无序的,且元素不能重复)
Set是一个接口,父接口是Collection,主要的实现类有HashSet、TreeSet等,继承关系图如下:

在这里插入图片描述

Set集合底层的实现原理

Set集合之所以无序是因为底层的算法是经过hash算法实现的(散列算法),计算的时候会计算出相应的元素的hashCode值(hash码)
每个元素的hash码不一样,导致该集合的元素是不能重复的和顺序没法保证。
(顺序是指添加元素的顺序与元素在集合里的顺序)
总结:HashSet集合在添加元素的时候
	如果元素对象的hashCode值和之前添加的hashCoode值一样:
那么HashSet集合会去比较两个元素对象的equals方法
如果equals方法比较相等,则认为两个元素是同一个对象,且最后一次添加的元素会替换上一次添加的元素;
如果equals方法比较不相等,那么认为这两个元素是不同的对象,那么这两个元素都会被添加到HashSet集合里
	如果元素对象的hashCode值和之前添加的hashCoode值不一样:
那么这两个元素都会被添加到HashSet集合里
注意:HashSet LinkedHashSet TreeSet的区别
相同点:
三者都是Set接口的子类实现
不同的:
HashSet是一个无序不可重复集(底层基于Hash算法实现)
LinkedHashSet是HashSet的一个子类,该类提供了一个线性表,维护了元素的添加顺序
TreeSet的父类是AbstractSet,AbstractSet的父类又是AbstractCollection,AbstractCollection的父类是Set集合,TreeSet的底层算法是基于黄黑树实现的,该算法保证了元素从小到大排序
Set集合测试
package com.tedu.cn.collections;

import com.tedu.cn.collections.entity.Student;
import org.junit.Test;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

public class Demo2 {
    /**
     * Set集合是无序不可重复集,当向Set里面添加元素的时候,
     * 如果发现本次添加的元素和前某一次添加的元素一样,
     * 那么最后添加的将会覆盖之前添加的元素
     */
    @Test
    public void m1() {
        //输出的顺序无法保证
        Set c1 = new HashSet();
        c1.add("语文");
        c1.add("数学");
        c1.add("英语");
        c1.add("语文");
        System.out.println(c1.size());
        for (Object o : c1) {
            System.out.println(o);
        }
    }

    @Test
    public void m2() {
        Student s1 = new Student("Jack01", "M", 18);
        Student s2 = new Student("Jack02", "G", 20);
        Student s3 = new Student("Jack03", "M", 19);
        Set c1 = new HashSet();
        System.out.println();
        c1.add(s1);
        c1.add(s2);
        c1.add(s3);
        s2.setsName("Make");
        c1.add(s2);
        System.out.println();
        //遍历集合
        for (Object o : c1) {
            if (o instanceof Student) {
                Student s = (Student) o;
                System.out.println(s);
            }
        }
    }

    @Test
    public void m3() {
        Student s1 = new Student("Jack01", "M", 18);
        Student s2 = new Student("Jack02", "G", 20);
        Student s3 = new Student("Jack03", "M", 18);
        Set c1 = new HashSet();
        c1.add(s1);
        c1.add(s2);
        c1.add(s3);
        //遍历集合
        for (Object o : c1) {
            if (o instanceof Student) {
                Student s = (Student) o;
                System.out.println(s);
            }
        }
    }

    /**
     * TreeSet和HashSet 都是无序不可重复集
     * 不同点就是底层的算法不一样
     * TreeSet是基于红黑树算法实现 HashSet是基于Hash算法实现
     * TreeSet底层基于红黑树维护元素的排序(从小到大) TreeSet无序
     *
     * Ctrl+N 搜索快捷键
     * Ctrl+H 查看类的继承关系
     */
    @Test
    public void m4() {
        Set c1 = new TreeSet();
        c1.add(8);
        c1.add(7);
        c1.add(6);
        c1.add(5);
        for (Object o : c1) {
            System.out.println(o);
        }
    }

    /**
     * LinkedHashSet是HashSet的一个子类,该类添加了一个线性链表来维护元素添加的顺序
     * 保证了集合里面元素的顺序和添加元素的顺序一样
     */
    public void m6(){
        Set c1=new LinkedHashSet();
        c1.add(8);
        c1.add(7);
        c1.add(6);
        c1.add(5);
        for (Object o : c1) {
            System.out.println(o);
        }
    }
}

涉及的Student类

package com.tedu.cn.collections.entity;

import java.util.Random;

public class Student {
    //学生姓名
    private String sName;
    //学生性别
    private String gender;
    //学生年龄
    private int age;

    public Student() {
    }

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

    public String getsName() {
        return sName;
    }

    @Override
    public String toString() {
        return "Student{" +
                "sName='" + sName + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                '}';
    }

//    @Override
//    public int hashCode() {
//        Random ran = new Random();
//        return ran.nextInt(999999999);
//    }


    @Override
    public int hashCode() {
        return 0;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj==null){
            return false;
        }
        if(obj instanceof Student){
            Student s= (Student) obj;
            return s.getAge()==this.getAge();
        }
        return false;
    }

    public void setsName(String sName) {
        this.sName = sName;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值