大数据必学Java基础(五十七):Set接口讲解

举报
Lansonli 发表于 2022/09/29 03:00:46 2022/09/29
【摘要】 ​Set接口讲解一、HashSet实现类的使用1、放入Integer类型数据package com.lanson.test07;import java.util.HashSet;/** * @author : lansonli */public class TestInteger { //这是main方法,程序的入口 public static void main(String[...

Set接口讲解

一、HashSet实现类的使用

1、放入Integer类型数据

package com.lanson.test07;

import java.util.HashSet;

/**
 * @author : lansonli
 */
public class TestInteger {
    //这是main方法,程序的入口
    public static void main(String[] args) {
        //创建一个HashSet集合:
        HashSet<Integer> hs = new HashSet<>();
        System.out.println(hs.add(19));//true
        hs.add(5);
        hs.add(20);
        System.out.println(hs.add(19));//false 这个19没有放入到集合中
        hs.add(41);
        hs.add(0);
        System.out.println(hs.size());//唯一,无序
        System.out.println(hs);

    }
}


2、放入String类型数据

package com.lanson.test07;

import java.util.HashSet;

/**
 * @author : lanson
 */
public class TestString {
    //这是main方法,程序的入口
    public static void main(String[] args) {
        //创建一个HashSet集合:
        HashSet<String> hs = new HashSet<>();
        hs.add("hello");
        hs.add("apple");
        hs.add("banana");
        hs.add("html");
        hs.add("apple");
        hs.add("css");
        System.out.println(hs.size());
        System.out.println(hs);
    }
}


3、放入自定义的引用数据类型的数据

package com.lanson.test07;

import java.util.HashSet;

/**
 * @author : lansonli
 */
public class TestStudent {
    //这是main方法,程序的入口
    public static void main(String[] args) {
        //创建一个HashSet集合:
        HashSet<Student> hs = new HashSet<>();
        hs.add(new Student(19,"lili"));
        hs.add(new Student(20,"lulu"));
        hs.add(new Student(18,"feifei"));
        hs.add(new Student(19,"lili"));
        hs.add(new Student(10,"nana"));
        System.out.println(hs.size());
        System.out.println(hs);
    }
}


上面自定义的类型不满足 唯一,无序的特点。为什么呢?

4、HashSet原理图:(简要原理图)

5、疑问

5.1、数组的长度是多少?

5.2、数组的类型是什么?

5.3、hashCode,equals方法真的调用了吗?

5.4、底层表达式是什么?

5.5、同一个位置的数据向前放还是向后放?

5.6、放入数组中的数据,是直接放的吗?是否封装为对象了?

二、LinkedHashSet使用

其实就是在HashSet的基础上,多了一个总的链表,这个总链表将放入的元素串在一起,方便有序的遍历:

可以看到LinkedHashMap.Entry 继承自HashMap.Node 除了Node 本身有的几个属性外,额外增加了before after 用于指向前一个Entry 后一个Entry。也就是说,元素之间维持着一条总的链表数据结构

代码:

package com.lanson.test07;

import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;

/**
 * @author : lansonli
 */
public class TestInteger {
    //这是main方法,程序的入口
    public static void main(String[] args) {
        //创建一个HashSet集合:
        LinkedHashSet<Integer> hs = new LinkedHashSet<>();
        System.out.println(hs.add(19));//true
        hs.add(5);
        hs.add(20);
        System.out.println(hs.add(19));//false 这个19没有放入到集合中
        hs.add(41);
        hs.add(0);
        System.out.println(hs.size());//唯一,无序
        System.out.println(hs);
    }
}


三、比较器的使用

1、以int类型为案例

比较的思路:将比较的数据做差,然后返回一个int类型的数据,将这个int类型的数值 按照 =0 >0 <0

int a = 10;
int b = 20;
System.out.println(a-b); // =0  >0  <0


2、比较String类型数据

String类实现了Comparable接口,这个接口中有一个抽象方法compareTo,String类中重写这个方法即可

String a = "A";
String b = "B";
System.out.println(a.compareTo(b));


3、比较double类型数据

double a = 9.6;
double b = 9.3;
/* System.out.println((int)(a-b));*/
System.out.println(((Double) a).compareTo((Double) b));


4、比较自定义的数据类型

4.1、内部比较器

package com.lanson.test08;

/**
 * @author : lansonli
 */
public class Student implements Comparable<Student>{
    private int age;
    private double height;
    private String name;

    public int getAge() {
        return age;
    }

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

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

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

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

    @Override
    public int compareTo(Student o) {
        //按照年龄进行比较:
        /*return this.getAge() - o.getAge();*/
        //按照身高比较
        /*return ((Double)(this.getHeight())).compareTo((Double)(o.getHeight()));*/
        //按照名字比较:
        return this.getName().compareTo(o.getName());
    }
}


package com.lanson.test08;

/**
 * @author : lansonli
 */
public class Test02 {
    //这是main方法,程序的入口
    public static void main(String[] args) {
        //比较两个学生:
        Student s1 = new Student(14,160.5,"alili");
        Student s2 = new Student(14,170.5,"bnana");
        System.out.println(s1.compareTo(s2));
    }
}


4.2、外部比较器

package com.lanson.test09;

import java.util.Comparator;

/**
 * @author : lansonli
 */
public class Student{
    private int age;
    private double height;
    private String name;

    public int getAge() {
        return age;
    }

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

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

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

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


}



class BiJiao01 implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        //比较年龄:
        return o1.getAge()-o2.getAge();
    }
}

class BiJiao02 implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        //比较姓名:
        return o1.getName().compareTo(o2.getName());
    }
}


class BiJiao03 implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        //在年龄相同的情况下 比较身高  年龄不同比较年龄
        if((o1.getAge()-o2.getAge())==0){
            return ((Double)(o1.getHeight())).compareTo((Double)(o2.getHeight()));
        }else{//年龄不一样
            return o1.getAge()-o2.getAge();
        }
    }
}


package com.lanson.test09;

import com.lanson.test09.Student;

import java.util.Comparator;

/**
 * @author : lansonli
 */
public class Test02 {
    //这是main方法,程序的入口
    public static void main(String[] args) {
        //比较两个学生:
        Student s1 = new Student(9,160.5,"alili");
        Student s2 = new Student(14,170.5,"bnana");
        //获取外部比较器:
        Comparator bj1 = new BiJiao03();
        System.out.println(bj1.compare(s1, s2));
    }
}


5、外部比较器和内部比较器谁好呀?

答案:外部比较器,多态,扩展性好

四、TreeSet实现类的使用

1、存入Integer类型数据(底层利用的是内部比较器)

package com.lanson.test10;

import java.util.TreeSet;

/**
 * @author : lansonli
 */
public class Test01 {
    //这是main方法,程序的入口
    public static void main(String[] args) {
        //创建一个TreeSet:
        TreeSet<Integer> ts = new TreeSet<>();
        ts.add(12);
        ts.add(3);
        ts.add(7);
        ts.add(9);
        ts.add(3);
        ts.add(16);
        System.out.println(ts.size());
        System.out.println(ts);

    }
}


特点:唯一,无序(没有按照输入顺序进行输出), 有序(按照升序进行遍历)

2、原理底层:二叉树(数据结构中的一个逻辑结构)

3、 放入String类型数据:(底层实现类内部比较器)

package com.lanson.test10;

import java.util.TreeSet;

/**
 * @author : lansonli
 */
public class Test02 {
    //这是main方法,程序的入口
    public static void main(String[] args) {
        //创建一个TreeSet:
        TreeSet<String> ts = new TreeSet<>();
        ts.add("elili");
        ts.add("blili");
        ts.add("alili");
        ts.add("elili");
        ts.add("clili");
        ts.add("flili");
        ts.add("glili");
        System.out.println(ts.size());
        System.out.println(ts);
    }
}


4、想放入自定义的Student类型的数据

4.1、利用内部比较器

package com.lanson.test10;

/**
 * @author : lansonli
 */
public class Student implements Comparable<Student> {
    private int age;
    private String name;

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

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

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


    @Override
    public int compareTo(Student o) {
        return this.getAge()-o.getAge();
    }
}


package com.lanson.test10;

import java.util.TreeSet;

/**
 * @author : lansonli
 */
public class Test03 {
    //这是main方法,程序的入口
    public static void main(String[] args) {
        //创建一个TreeSet:
        TreeSet<Student> ts = new TreeSet<>();
        ts.add(new Student(10,"elili"));
        ts.add(new Student(8,"blili"));
        ts.add(new Student(4,"alili"));
        ts.add(new Student(9,"elili"));
        ts.add(new Student(10,"flili"));
        ts.add(new Student(1,"dlili"));
        System.out.println(ts.size());
        System.out.println(ts);
    }
}


4.2、通过外部比较器

package com.lanson.test10;

import java.util.Comparator;

/**
 * @author : lansonli
 */
public class Student  {
    private int age;
    private String name;

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

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

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



}

class BiJiao implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
        return o1.getName().compareTo(o2.getName());
    }
}


package com.lanson.test10;

import java.util.Comparator;
import java.util.TreeSet;

/**
 * @author : lansonli
 */
public class Test03 {
    //这是main方法,程序的入口
    public static void main(String[] args) {
        //创建一个TreeSet:
        //利用外部比较器,必须自己制定:
        Comparator<Student> com = new BiJiao();
        TreeSet<Student> ts = new TreeSet<>(com);//一旦指定外部比较器,那么就会按照外部比较器来比较
        ts.add(new Student(10,"elili"));
        ts.add(new Student(8,"blili"));
        ts.add(new Student(4,"alili"));
        ts.add(new Student(9,"elili"));
        ts.add(new Student(10,"flili"));
        ts.add(new Student(1,"dlili"));
        System.out.println(ts.size());
        System.out.println(ts);
    }
}


实际开发中利用外部比较器多,因为扩展性好(多态)

换一种写法:

package com.lanson.test10;

import java.util.Comparator;
import java.util.TreeSet;

/**
 * @author : lansonli
 */
public class Test03 {
    //这是main方法,程序的入口
    public static void main(String[] args) {
        //创建一个TreeSet:
        //利用外部比较器,必须自己制定:
        /*Comparator<Student> com = new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getName().compareTo(o2.getName());
            }
        };*/
        TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });//一旦指定外部比较器,那么就会按照外部比较器来比较
        ts.add(new Student(10,"elili"));
        ts.add(new Student(8,"blili"));
        ts.add(new Student(4,"alili"));
        ts.add(new Student(9,"elili"));
        ts.add(new Student(10,"flili"));
        ts.add(new Student(1,"dlili"));
        System.out.println(ts.size());
        System.out.println(ts);
    }
}


5、TreeSet底层的二叉树的遍历是按照升序的结果出现的,这个升序是靠中序遍历得到的

五、Collection部分整体结构图

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。