前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大数据必学Java基础(五十七):Set接口讲解

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

原创
作者头像
Lansonli
发布2022-09-29 02:59:05
3090
发布2022-09-29 02:59:05
举报
文章被收录于专栏:Lansonli技术博客Lansonli技术博客

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部分整体结构图

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ​Set接口讲解
    • 一、HashSet实现类的使用
      • 1、放入Integer类型数据
      • 2、放入String类型数据
      • 3、放入自定义的引用数据类型的数据
      • 4、HashSet原理图:(简要原理图)
      • 5、疑问
    • 二、LinkedHashSet使用
      • 三、比较器的使用
        • 1、以int类型为案例
        • 2、比较String类型数据
        • 3、比较double类型数据
        • 4、比较自定义的数据类型
        • 5、外部比较器和内部比较器谁好呀?
      • 四、TreeSet实现类的使用
        • 1、存入Integer类型数据(底层利用的是内部比较器)
        • 2、原理底层:二叉树(数据结构中的一个逻辑结构)
        • 3、 放入String类型数据:(底层实现类内部比较器)
        • 4、想放入自定义的Student类型的数据
        • 5、TreeSet底层的二叉树的遍历是按照升序的结果出现的,这个升序是靠中序遍历得到的
      • 五、Collection部分整体结构图
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档