Java中set系列集合

一.Set系列集合特点

1.无序:存取顺序不一致

2.重复性:不可重复,可以用于去重操作

3.无索引:不可以使用for循环遍历,无法通过索引获取元素,可以通过foreach和Ierator接口遍历

二.Set集合的实现类特点

HashSet:无序、不重复、无索引

LinkedHashSet:有序、不重复、无索引

TreeSet:可排序、不重复、无索引

由于Set是Collection的接口(接口无法被实例化),继承于Collection,所以Set接口中的方法基本上与Collection的相同。

三.Collection接口

方法声明功能描述

boolean add(Object o)

向集合中添加一个元素

boolean addAll(Collection c)

将指定集合c中的所有元素添加到该集合中

void clear()

删除该集合中的所有元素

boolean remove(Object o)

删除该集合中指定的元素

boolean removeAll(Collection c)

删除该集合中包含指定集合c中的所有元素(set集合中只能通过对象删除,set中没有索引)

boolean isEmpty()

判断该集合是否为空

boolean contains(Object o)

判断该集合中是否包含某个元素

boolean containsAll(Collection c)

判断该集合中是否包含指定集合c中的所有元素

Iterator iterator()

返回在该集合的元素上进行迭代的迭代器(Iterator),用于遍历该集合所有元素

int size()

获取该集合元素个数

Stream<E> stream()

将集合源转换为有序元素的流对象(JDK 8新方法)

四.储存Set集合和遍历

1.储存:使用add接口添加字符串

2.遍历:

(1.)迭代器

  public static void main(String[] args) {
//        创建set集合对象
        Set<String> s=new HashSet<>();
//        添加元素
        s.add("123");
        s.add("123");   //这个会被删除,set集合不可重复
        s.add("456");
        s.add("789");
//        迭代器遍历
        Iterator<String> it=s.iterator();
        while (it.hasNext()){    //判断当前指向的位置是否有元素
         String str  = it.next();
            System.out.println(str);
        }
    }

(2)增强for

public static void main(String[] args) {
//        创建set集合对象
        Set<String> s=new HashSet<>();
//        添加元素
        s.add("123");
        s.add("123");   //这个会被删除,set集合不可重复
        s.add("456");
        s.add("789");
//        增强for
        for (String string : s) {
            System.out.println(string);
        }
    }

 (3)foreach

    public static void main(String[] args) {
//        创建set集合对象
        Set<String> s=new HashSet<>();
//        添加元素
        s.add("123");
        s.add("123");   //这个会被删除,set集合不可重复
        s.add("456");
        s.add("789");
//        foreach
        s.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

    }

运行结果:

五.HashSet

  1. HashSet底层原理
  • HashSet集合底层采取哈希表存储数据
  • 哈希表是一种对于增删改查数据性能都较好的结构
  • 创建一个默认长度16,默认加载因为0.75的数组,数组名table
  • 根据元素的哈希值跟数组的长度计算出应存入的位置
  • 判断当前位置是否为null,如果是null直接存入
  • 如果当前位置不为null,表示有元素,则调用equals方法比较属性值
  • 在集合中存储的是自定义对象,必须要重写hashCode

     2.Hash值

  • 根据hashCode方法算出来的int类型的整数
  • 一般情况下,会重写hashCode方法,利用对象内部的属性值计算哈希值

     3.Hash值特点

  • 如果没有重写hashCode方法,不同对象计算出的哈希值是不同的
  • 如果已经重写hashCode方法,不同的对象只要属性值相同,计算出的哈希值就是一样的

   4HashSet去重

public class Student {
        private String stuNo;
        private String stuName;
        private int stuAge;
        private int stuScore;
    private Object Integer;

    public String getStuNo() {
            return stuNo;
        }

        public void setStuNo(String stuNo) {
            this.stuNo = stuNo;
        }

        public String getStuName() {
            return stuName;
        }

        public void setStuName(String stuName) {
            this.stuName = stuName;
        }

        public int getStuAge() {
            return stuAge;
        }

        public void setStuAge(int stuAge) {
            this.stuAge = stuAge;
        }

        public int getStuScore() {
            return stuScore;
        }

        public void setStuScore(int stuScore) {
            this.stuScore = stuScore;
        }

        public Student(String stuNo, String stuName, int stuAge,int stuScore) {
            this.stuNo = stuNo;
            this.stuName = stuName;
            this.stuAge = stuAge;
            this.stuScore = stuScore;
        }

    @Override
    public boolean equals(Object o) {  //重写equals方法
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return stuAge == student.stuAge && stuScore == student.stuScore && Objects.equals(stuNo, student.stuNo) && Objects.equals(stuName, student.stuName) && Objects.equals(Integer, student.Integer);
    }

    @Override
    public int hashCode() {
        return Objects.hash(stuNo, stuName, stuAge, stuScore, Integer);
    }//重写hashCode方法

    public void printInfo() {
            System.out.println("学号: " + stuNo +"姓名:"+stuName+"年龄:"+stuAge+"成绩:"+stuScore);
        }
    }

 测试类:

public static void main(String[] args) {
        Student stu1 = new Student("001", "张三", 19, 90);
        Student stu2 = new Student("002", "李四", 20, 91);
        Student stu3 = new Student("002", "李四", 20, 91);//与第二个相同通过重写hashcode和equals方法进行去重
        Set<Student> stus = new HashSet<>();
        //true代表添加成功,false代表没有添加成功
        System.out.println(stus.add(stu1));//true
        System.out.println(stus.add(stu2));//true
        System.out.println(stus.add(stu3));//false
    }

运行结果:

 六.LinkedHashSet

  1. LinkedHashSet底层原理
  • LinkedHashSet存储和取出的元素顺序一致
  • LinkedHashSet使用双链表数据结构同来记录存储顺序(双链表的每一个节点都会存储上个节点和下个节点的地址)

     2.LinkedHashSet的特点

  • LinkedHashSet打印时和添加时的顺序是一样的
  • 去重:与HashSet相似(需要重写equals和hashCode)
  • 遍历:与HashSet相似(Iterator ,增强for,foreach)
  • 数据去重优先选择HashSet,如果存取需要有序才使用LinkedHashSet

七.TreeSet

  1. TreeSet的特点
  • 不重复、无索引、可排序
  • 可排序:按照元素的默认规则(由大到小)排序
  • TreeSet增删改查性能比较好

      2.TreeSet遍历

  • Iterator
  • 增强for
  • forEach

     3.TressSet排序

  • 匿名内部类
public static void main(String[] args) {
		// TODO Auto-generated method stub
        Student stu1=new Student("001", "张三", 20, 95);
        Student stu2=new Student("002", "李四", 19, 92);
        Student stu3=new Student("003", "王五", 22, 98);
        Student stu4=new Student("004", "赵六", 21, 93);
        Student stu5=new Student("005", "江晋义", 23, 97);
        Student stu6=new Student("006", "裴承家", 20, 90);
        Student stu7=new Student("007", "傅柏辰", 20, 92);
        Student stu8=new Student("008", "林雨晨", 18, 100);
        
        Set<Student> se1=new TreeSet<>(new Comparator<Student>() {

			@Override
			public int compare(Student o1, Student o2) {
				// TODO Auto-generated method stub
				return o1.getStuScore()-o2.getStuScore();//从小到大排序规则
			}
        	
		});
        se1.add(stu1);
        se1.add(stu2);
        se1.add(stu3);
        se1.add(stu4);
        se1.add(stu5);
        se1.add(stu6);
        se1.add(stu7);
        se1.add(stu8);
        for (Student student : se1) {//集合遍历
			student.printInfo();
		}
}
  • 外部类
  • public class Comp implements Comparator<Student> {//调用Comparator接口
    
    	@Override
    	public int compare(Student arg0, Student arg1) {
    		// TODO 自动生成的方法存根
    		return arg1.getStuAge()-arg0.getStuAge();//从大到小排序规则
    	}
    
    }
    //测试类
    public static void main(String[] args) {
    		// TODO Auto-generated method stub
            Student stu1=new Student("001", "张三", 20, 95);
            Student stu2=new Student("002", "李四", 19, 92);
            Student stu3=new Student("003", "王五", 22, 98);
            Student stu4=new Student("004", "赵六", 21, 93);
            Student stu5=new Student("005", "江晋义", 23, 97);
            Student stu6=new Student("006", "裴承家", 20, 90);
            Student stu7=new Student("007", "傅柏辰", 20, 92);
            Student stu8=new Student("008", "林雨晨", 18, 100);
            Comp comp=new Comp();
            Set<Student> se2=new TreeSet<>(comp);
            se2.add(stu1);
            se2.add(stu2);
            se2.add(stu3);
            se2.add(stu4);
            se2.add(stu5);
            se2.add(stu6);
            se2.add(stu7);
            se2.add(stu8);
            for (Student student : se2) {
    			student.printInfo();
    		}
            
    	}
    	
    }
    

第一次写博客,如果有错误的地方欢迎大家提出来,都可以互相交流学习!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值