Java集合之Set知识点汇总

501 阅读3分钟

Set集合

这是我参与8月更文挑战的第19天,活动详情查看:8月更文挑战

主要特点是:内部不允许保存重复元素

继承结构如下:

public interface Set<E> extends Collection<E>

核心代码:

    //不能有重复值,如果有的话会报错
    //Exception in thread "main" java.lang.IllegalArgumentException: duplicate element: 世界
    //Set<String> all = Set.of("你好","xbhog","世界","世界");
    Set<String> all = Set.of("你好","xbhog","世界");
    System.out.println(all);

HashSet子类:

特点:散列存放且不允许保存重复元素 即:无序存放

继承结构如下:

public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable

HashSet保存数据:

//数据采用无序的保存方式,且不允许保存重复的数据
    //保存的类型是String
    Set<String> all = new HashSet<String>();
    all.add("小李");
    all.add("小红");
    all.add("小1");
    all.add("小2");
    all.add("小花");
    all.add("小花");
    System.out.println(all);
    Iterator<String> iter = all.iterator();
    while(iter.hasNext()){
        String str  = iter.next();
        System.out.print(str+"、");
    }

LinkedHashSet子类:JDK1.4加入---解决HashSet无法顺序保存的数据

实现是基于链表保存的数据:增加的顺序就是集合的保存顺序,且不会保存重复的数据。

//基于链表的操作,且保存的数据为顺序保存
        Set<String> all = new LinkedHashSet<String>();
        all.add("小李老师");
        all.add("小bai");
        all.add("小明");
        all.add("小黄");
        System.out.println(all);
        Iterator<String> iter = all.iterator();
        while (iter.hasNext()) {
            String str = iter.next();
            System.out.println(str + "、");
        }

TreeSet子类:

特点:使得集合中保存的数据进行有序排列

其继承结构如下:

public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, Serializable

TreeSet子类继承AbstractSet抽象类并实现了NavigableSet接口(该接口为排序标准接口,是Set的子类)

TreeSet保存数据:

package Java从入门到项目实战.Java类集框架.Set集合;
import java.util.*;
public class TreeSet子类的有序排列 {
    //所有保存的数据按照从大到小的顺序(字符按照字母大小顺序依次比较)
    public static void main(String[] args) {
        Set<String> all = new TreeSet<String>();
        all.add("11");
        all.add("hello");
        all.add("hello");
        all.add("world");
        all.add("add");
        all.add("部署");
        all.add("啊哈");
        System.out.println(all);
    }
}

优先级:数字排序>字母排序>汉字排序

TreeSet子类排序分析:

该子类在进行有序数据存储时依据的是Comparable接口实现排序;需要注意的是在覆写compareTo()方法时需要进行类中全部属性的比较;否则出现部分属性相同时被误判为同一个对象;导致重复元素判断失败;

package Java从入门到项目实战.Java类集框架.Set集合;
import java.util.Set;
import java.util.TreeSet;
class Member implements Comparable<Member>{
    private  String name;
    private  int age;
    public Member(String name,int age){
        this.name = name;
        this.age = age;
    }
    public String toString(){
        return "姓名:"+this.name +"、年龄:"+this.age;
    }
    @Override
    public int compareTo(Member per){
        if(this.age < per.age) return -1;
        else if(this.age > per.age) return 1;  //年龄相同时比较名字
        else {
            return this.name.compareTo(per.name);
        }
    }
}

public class TreeSet子类排序分析 {
    public static void main(String[] args) {
        Set<Member> all = new TreeSet<Member>();
        all.add(new Member("张三",12));
        all.add(new Member("李四",12));
        all.add(new Member("王五",20));
        all.add(new Member("王五",20));
        all.forEach(System.out::println);
    }
}

关于compareTo的相关描述,可以到源码下的注释中翻译了解。

重复元素消除:(非排序的集合中的重复元素)

依靠两种方法:

  1. Hash码:public int Hashcode();
  2. 对象比较:public boolean equals(Object obj);

在进行对象比较的过程中,首先会使用hashCode()方法与集合中已经保存的代码进行匹配比较;如果代码相同则再使用equals()方法进行属性的依次比较;如果全部相同;则为相同元素;

package Java从入门到项目实战.Java类集框架.Set集合;
import java.util.*;
class Person{
    private String name;
    private int age;
    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Person)) return false;

        Person person = (Person) o;

        if (age != person.age) return false;
        if (name != null ? !name.equals(person.name) : person.name != null) return false;

        return true;
    }
    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }
}
public class 重复元素消除 {
    public static void main(String[] args) {
        Set<Person> all = new HashSet<Person>();
        all.add(new Person("张三",19));
        all.add(new Person("李四",19));
        all.add(new Person("王五",20));
        all.add(new Person("王五",20));
        all.add(new Person("魏六",66));
        all.add(new Person("xbhog",10));
        System.out.println("------------第一种输入方式-----------");
        all.forEach((person -> {
            System.out.println(person.getName()+"----"+person.getAge());
        }));
        System.out.println("------------第二种输入方式-----------");
        Iterator<Person> iter = all.iterator();
        while(iter.hasNext()){
            Person per = iter.next();
            System.out.println(per.getName() + " "+per.getAge());
        }
    }
}

通过hashSet 保存了重复元素,再使用equals与hashCode方法实现去重操作。

结束:

如果你看到这里或者正好对你有所帮助,希望能点个👍或者★,感谢;

有错误的地方,欢迎在评论指出,作者看到会进行修改。