一篇文章让你精通:java集合讲解(三,Set)

26 篇文章 1 订阅
13 篇文章 0 订阅

一篇文章让你精通:java集合讲解(二,ArrayList)

一篇文章让你精通:java集合讲解(二,LinkList)

上面二个链接,让大家对集合中的List有了一定的了解,如果大家回想要继续加强理解,建议大家打开jdk8下的List源码继续解析一下。废话不多说下面让我们来看看Set的内容吧!

目录

Set

HashSet

linkedHashSet

TreeSet

set的遍历方法(三种方法,无序:不能使用for循环)

练习:set存储自定义类的对象与操作(存储学生信息)

问题发现

解决问题一:在Student类下重写equals与 hashCode方法(缺一不可)。

 解决问题2:在Student在threeSet下重写compareTo的比较方法(按照姓名比较),这样使用treeHash就不会报错了。

报错显示:java.lang.ClassCastException: com.itheima.类名称 cannot be cast to java.lang.Comparable


Set

特点:无序,唯一(数据不重复) 

HashSet

特点:采用HashSet哈希表存储结构。

优点:添加速度快,查询速度快,删除速度快。

缺点:无序

HashSet的常用方法

add()
 

末尾添加元素,
数组能自动装箱:就是数组封装。普通数据类型——>包装类
可以使用一个参数或者二个,一个时,添加元素,二个时,第一个参数:索引,第二个,添加元素
addAll(对象)
addAll(下标,对象)

复制添加对象全部元素,默认在后面添加

当有二个参数后,表示在下标后添加对象全部元素。

remove()当输入的是对象时,删除对象,当输入的是对下标,删除下标,
el1.removeAll(el2)在el1中删除el2中相同的元素。
list.retainAll(list2);在list中查找与list2相同的元素
clear()   清空数组
contains(value)判断是否存在value值,返回布尔值
isEmpty()判断数组是否为空。
size()查看数组中真实存储的元素个数。与数组的length()方法返回不同
toString()遍历数组

import java.util.HashSet;
import java.util.Set;

public class Test {
    public static void main(String[] args)  {
        //创建Set集合数组
        Set<String> set= new HashSet();

        //添加元素
        set.add("javaSE");
        set.add("javaEE");
        set.add("english");
        set.add("中文");
        //可以添加相同的数据,但不会添加到集合中
        set.add("javaSE");

        //查看数量
        System.out.println(set.size());

        //遍历元素
        System.out.println(set);
        for (String ss:set) {
            System.out.println(ss);
        }
        //数据清空
        set.clear();



    }


}

linkedHashSet

HashSet的子类,采用哈希表存储结构,同时使用了链表维护次序,有序(添加顺序)



import java.util.LinkedHashSet;
import java.util.Set;

public class Test {
    public static void main(String[] args)  {
        //创建Set集合数组,有序,但是是存储的先后顺序
        Set<String> set= new LinkedHashSet();

        //添加元素
        set.add("javaSE");
        set.add("javaEE");
        set.add("english");
        set.add("中文");
        //可以添加相同的数据,但不会添加到集合中
        set.add("javaSE");

        //查看数量
        System.out.println(set.size());

        //遍历元素
        System.out.println(set);
        for (String ss:set) {
            System.out.println(ss);
        }
        //数据清空
        set.clear();



    }


}

TreeSet

特点:采用二叉树(红黑树,左子数小于根,右子树大于根,左右平衡)的存储结构

优点:有序,查询速度比List快(按照内容进行查找)

缺点:查询速度比HashSet快

TreeSet的常用方法

add()
 

末尾添加元素,
数组能自动装箱:就是数组封装。普通数据类型——>包装类
可以使用一个参数或者二个,一个时,添加元素,二个时,第一个参数:索引,第二个,添加元素
addAll(对象)
addAll(下标,对象)

复制添加对象全部元素,默认在后面添加

当有二个参数后,表示在下标后添加对象全部元素。

remove()当输入的是对象时,删除对象,当输入的是对下标,删除下标,
el1.removeAll(el2)在el1中删除el2中相同的元素。
list.retainAll(list2);在list中查找与list2相同的元素
clear()   清空数组
contains(value)判断是否存在value值,返回布尔值
isEmpty()判断数组是否为空。
size()查看数组中真实存储的元素个数。与数组的length()方法返回不同
toString()遍历数组

import java.util.Set;
import java.util.TreeSet;

public class Test {
    public static void main(String[] args)  {
        //创建Set集合数组,有序,但是是存储的先后顺序
        Set<String> set= new TreeSet();

        //添加元素
        set.add("javaSE");
        set.add("javaEE");
        set.add("english");
        set.add("中文");
        //可以添加相同的数据,但不会添加到集合中
        set.add("javaSE");

        //查看数量
        System.out.println(set.size());

        //遍历元素
        System.out.println(set);
        for (String ss:set) {
            System.out.println(ss);
        }
        //数据清空
        set.clear();



    }


}

set的遍历方法(三种方法,无序:不能使用for循环)

 //遍历元素 for-each
        System.out.println(set);
        for (String ss:set) {
            System.out.println(ss);
        }
        //遍历元素 迭代器
        Iterator<String> it=set.iterator();
        while (it.hasNext()){
            String elem =it.next();
            System.out.println(elem);
        }
        //遍历元素 lambda表达式
        set.forEach((elem)-> System.out.println(elem+" "));

练习:set存储自定义类的对象与操作(存储学生信息)

一,先定义一个学生的ApI.

(IDEA工具快速生成快捷键:Alt+insert)



import java.util.Objects;

//一个完整的API
public class Student implements Comparable<Student> {
    //姓名
    private String name;
    //性别
    private String sex;
    //年龄
    private int age;
    //分数
    private double score;
    
    //重写TreeSet的比较规则
    @Override
    public int compareTo(Student other){
        return this.name.compareTo(other.name);
    }

    public Student() {
        //无参构造
    }

    public Student(String name, String sex, int age, double soore) {
        //有参构造
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.score = score;
    }

    //生成get方法
    public String getName() {
        return name;
    }

    public String getSex() {
        return sex;
    }

    public int getAge() {
        return age;
    }

    public double getScore() {
        return score;
    }

    //生成set方法
    public void setName(String name) {
        this.name = name;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

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

    public void setScore(double score) {
        this.score = score;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Double.compare(student.score, score) == 0 &&
                Objects.equals(name, student.name) &&
                Objects.equals(sex, student.sex);
    }

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

    //生成toString方法
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}

二,进行学生添加到set中


import java.util.HashSet;
import java.util.Set;


public class Test {
    public static void main(String[] args)  {
        //创建Set集合数组,存储学生信息。
        Set<Student> set= new HashSet();

        //使用set存储多个学生信息
        Student stu1= new Student("张三","男",18,60);
        Student stu2= new Student("李四","男",28,75);
        Student stu3= new Student("小明","男",20,90);
        Student stu4= new Student("小美","女",18,100);
        Student stu5= new Student("Jack","女",18,100);
        //插入数据重复的信息看看现象
        Student stu6= new Student("Jack","女",18,100);

        //添加到Set中
        set.add(stu1);
        set.add(stu2);
        set.add(stu3);
        set.add(stu4);
        set.add(stu5);
        set.add(stu6);

        //查看数量
        System.out.println(set.size());

        //遍历元素 for-each
        System.out.println(set);
        for (Student student1:set) {
            System.out.println(student1);
        }
        //遍历元素 迭代器
//        Iterator<Student> it=set.iterator();
//        while (it.hasNext()){
//            Student elem =it.next();
//            System.out.println(elem);
//        }
        //遍历元素 lambda表达式
//        set.forEach((elem)-> System.out.println(elem+" "));

        //数据清空
//        set.clear();
    }
}

问题发现

1,HashSet存储Steing是唯一的,但在存储Student对象时不唯一?

Steing是系统写好的内部类,有equals与 hashCode方法,所以当我们使用时需要重写。

2,当Treeset存储String是有序的,但存储Student对象时却报异常(类型转化异常)?

在Student在threeSet下没有compareTo比较方法?

原因:String是系统类,做了一些其他操作,而student是自定义类,一些操作没有做

解决问题一:在Student类下重写equals与 hashCode方法(缺一不可)。

 @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Double.compare(student.score, score) == 0 &&
                Objects.equals(name, student.name) &&
                Objects.equals(sex, student.sex);
    }

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

现象:

 解决问题2:在Student在threeSet下重写compareTo的比较方法(按照姓名比较),这样使用treeHash就不会报错了。

 //重写TreeSet的比较规则
    @Override
    public int compareTo(Student other){
        return this.name.compareTo(other.name);
    }

报错显示:java.lang.ClassCastException: com.itheima.类名称 cannot be cast to java.lang.Comparable

在使用TreeSet时,发生的报错:原因就是在自定义类在ThreeSet下没有compareTo比较方法?

解决办法:

public class 自定义类 implements Comparable<Student> {
  
    //重写TreeSet的比较规则
    @Override
    public int compareTo(自定义类 other){
        return this.name.compareTo(other.属性);
    }

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
非常感谢您的提问,我很乐意为您解答关于JAVA的ArrayList集合的问题。 ArrayList是JAVA中最常用的集合之一,它是一个动态数组,可以根据需要自动扩展大小。ArrayList可以存储任何类型的对象,包括基本数据类型和自定义对象。下面是一些关于ArrayList的详细讲解: 1. ArrayList的创建和初始化 在JAVA中,创建ArrayList对象的语法如下: ArrayList<数据类型> arrayList = new ArrayList<数据类型>(); 其中,数据类型可以是任何JAVA中的数据类型,例如:Integer、String、Double等等。初始化ArrayList对象后,可以使用add()方法向其中添加元素,例如: arrayList.add("Hello"); arrayList.add("World"); arrayList.add("!"); 2. ArrayList的常用方法 ArrayList提供了许多常用的方法,例如: - add():向ArrayList中添加元素 - get():获取ArrayList中指定位置的元素 - set():替换ArrayList中指定位置的元素 - remove():从ArrayList中删除指定元素 - size():获取ArrayList中元素的数量 - clear():清空ArrayList中的所有元素 下面是一些示例代码: // 添加元素 arrayList.add("Java"); arrayList.add("is"); arrayList.add("awesome"); // 获取元素 String firstElement = arrayList.get(0); System.out.println(firstElement); // 输出:Java // 替换元素 arrayList.set(1, "really"); System.out.println(arrayList); // 输出:[Java, really, awesome] // 删除元素 arrayList.remove("Java"); System.out.println(arrayList); // 输出:[really, awesome] // 获取元素数量 int size = arrayList.size(); System.out.println(size); // 输出:2 // 清空ArrayList arrayList.clear(); System.out.println(arrayList); // 输出:[] 3. ArrayList的遍历 遍历ArrayList可以使用for循环或者foreach循环,例如: // 使用for循环遍历ArrayList for (int i = 0; i < arrayList.size(); i++) { String element = arrayList.get(i); System.out.println(element); } // 使用foreach循环遍历ArrayList for (String element : arrayList) { System.out.println(element); } 4. ArrayList的性能 ArrayList的性能比较高,因为它是基于数组实现的,可以随机访问元素。但是,当需要频繁插入或删除元素时,ArrayList的性能会受到影响,因为需要移动数组中的元素。在这种情况下,可以考虑使用LinkedList。 总之,ArrayList是JAVA中非常常用的集合之一,它提供了许多常用的方法,可以方便地操作元素。希望我的回答能够帮助您更好地理解ArrayList。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韶光不负

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值