集合框架学习之——Set

Set是一个不包含重复元素的 collection。

Set有三个重要的实现类:HashSet,LinkedHashSet,TreeSet,下面讲解这三个实现类。

 

一:HashSet底层是哈希表构成,它不保证set的迭代顺序,特别是它不保证该顺序恒久不变。此类允许使用 null 元素。

下面用代码演示为什么HashSet不保证set的迭代顺序:

import java.util.HashSet;

public class HashSetDemo {
    public static void main(String[] args) {
        HashSet<Integer> hashSet=new HashSet<>();
        //放三个Integer对象
        hashSet.add(23);
        hashSet.add(324);
        hashSet.add(456);

        //遍历输出
        for(Integer ele:hashSet){
            System.out.println(ele);
        }
    }
}

它的输出结果是:

 

HashSet有两种遍历方法:

import java.util.HashSet;
import java.util.Iterator;

public class HashSetDemo {
    public static void main(String[] args) {
        HashSet<Integer> hashSet=new HashSet<>();
        hashSet.add(23);
        hashSet.add(324);
        hashSet.add(456);
        hashSet.add(678);
        hashSet.add(12);
        //使用增强for循环遍历
        for(Integer ele:hashSet){
            System.out.println(ele);
        }
        System.out.println("-------------------------");

        //使用 Iterable接口提供的迭代器进行遍历
        Iterator ite=hashSet.iterator();
        while(ite.hasNext()){
            System.out.println(ite.next());
        }
    }
}

 

二:LinkedHashSet是具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。

此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。注意,插入顺序 受在 set 中重新插入的 元素的影响。

此类提供所有可选的 Set 操作,并且允许 null 元素。

由于增加了维护链接列表的开支,其性能很可能会比 HashSet 稍逊一筹,不过,这一点例外:LinkedHashSet 迭代所需时间与 set 的大小 成正比,而与容量无关。HashSet 迭代很可能支出较大,因为它所需迭代时间与其容量 成正比。

LinkedHashSet有两种遍历方法:

import java.util.Iterator;
import java.util.LinkedHashSet;

public class LinkerHashSetDemo {
    public static void main(String[] args) {
        LinkedHashSet<Integer> lhS=new LinkedHashSet<>();
        lhS.add(123);
        lhS.add(423);
        lhS.add(543);
        lhS.add(321);
        lhS.add(654);

        //使用增强for循环进行遍历
        for (Integer ele:lhS){
            System.out.println(ele);
        }
        System.out.println("--------------------");
        //使用Iterable接口提供的迭代器
        Iterator ite=lhS.iterator();
        while(ite.hasNext()){
            System.out.println(ite.next());
        }
    }
}

 

三:TreeSet使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的Comparator 进行排序,具体取决于使用的构造方法。

注意:如果是元素为自定义对象,一定要实现Comparable接口,否则无法进行排序。

下面我先定义一个对象为Integer对象的TreeSet,演示一下自然排序:

import java.util.TreeSet;

public class TreeSetDemo3 {
    public static void main(String[] args) {
        TreeSet<Integer> treeSet=new TreeSet<>();
        treeSet.add(64);
        treeSet.add(15);
        treeSet.add(236);
        treeSet.add(184);
        treeSet.add(345);

        for(Integer ele:treeSet){
            System.out.println(ele);
        }
    }
}

输出结果是:

 

下面我定义一个存储自定义对象的TreeSet:

先是自定义对象类:

public class Student {
    private String name;
    private int age;

    public Student(String 楚留香, int i, int i1, int i2) {
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class TreeSetDemo2 {
    public static void main(String[] args) {
        //这里我使用匿名内部类传进去一个比较器,该比较器使用总分进行排序
        TreeSet<StudentScore> stu=new TreeSet<>(new Comparator<StudentScore>() {
            @Override
            public int compare(StudentScore a, StudentScore b) {
                int anum=a.getCscore()+a.getEscore()+a.getMscore();
                int bnum=b.getCscore()+b.getEscore()+b.getMscore();
                int num=(anum-bnum)==0?a.getName().compareTo(b.getName()):(anum-bnum);
                return -num;
            }
        });
        StudentScore stu1=new StudentScore("楚留香",98,95,97);
        StudentScore stu2=new StudentScore("陆小凤",95,96,94);
        StudentScore stu3=new StudentScore("李寻欢",93,91,93);
        StudentScore stu4=new StudentScore("小鱼儿",99,97,89);

        stu.add(stu1);
        stu.add(stu2);
        stu.add(stu3);
        stu.add(stu4);

        for(StudentScore ele:stu){
            System.out.println(ele);
        }
    }
}

运行结果是:

 

这个例子我是使用匿名内部类传进去一个比较器,大家也可以在Student类中实现Comparable接口,然后重写compareTo方法,这两个方法都可以。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值