set集合

 目录

HashSet存储字符串并遍历

HashSet存储自定义对象保证元素的唯一性

HashSet如何保证元素唯一性原理

LinkedHashSet的概述

产生10个1-20之间的随机数要求随机数不能重复

练习

TreeSet存储integer类型的元素并遍历

TreeSet存储自定义对象

TreeSet保证元素唯一和比较器排序的原理以及代码实现

TreeSet原理

练习


HashSet存储字符串并遍历

hashset是通过哈希表支持,他不保证set的迭代顺序,特别是不保证该顺序恒久不变,此类允许添加NULL元素

import java.util.HashSet;

public class demo {
	//set集合,无索引,不可以重复,无序(存取不一致)
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		HashSet<String> hs = new HashSet<>();
		boolean b1= hs.add("a");
		boolean b2= hs.add("a");  //当向set集合中存储重复元素的时候返回为false
		hs.add("b");
		hs.add("c");
		hs.add("d");
		
		System.out.println(b1); //true
		System.out.println(b2); //false
		System.out.println(hs); //HashSet的继承体系中有重写toString方法
		
		for(String string :hs) {
			System.out.println(string);     //只要能用迭代器迭代的就能使用增强for循环遍历
		}
	}

}

HashSet存储自定义对象保证元素的唯一性

import java.util.HashSet;

import com.P.Person;

public class demo1 {
	public static void main(String[] args) {
		HashSet<Person> hs = new HashSet<>();
		hs.add(new Person("张三",23));
		hs.add(new Person("张三",23));
		hs.add(new Person("李四",23));
		hs.add(new Person("李四",23));
		hs.add(new Person("李四",23));
		
		System.out.println(hs); //全部都存储进来,由于对象的地址值不同
    //重写Person中的hashcode()以及equals()
	}
}

由于HashCode()通过对象地址值来计算出值,然后再决定改对象存储在什么位置,需不需要进equals方法,由于地址值一直都不一样,因此直接不调用equals方法。所以要重写hashcode()以及equals()方法。

如下

    @Override
	public int hashCode() {
		return Objects.hash(age, name);
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		return age == other.age && Objects.equals(name, other.name);
	}
	
	

HashSet如何保证元素唯一性原理

我们使用Set集合都是需要去掉重复元素的,如果在存储的时候逐个equals()比较,效率较低,哈希算法提高了去重复的效率,降低了使用equals()方法的次数

当HashSet()调用add()方法存储对象时,先调用对象的HashCode()方法得到一个哈希值,然后在集合中查找是否有哈希值相同的对象

如果没有哈希值相同的对象就直接存入集合

如果有哈希值相同的对象,就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入,true就不存入

将自定义类的对象存入HashSet去重复

        类中必须重写hashcode()和equals()方法

        hashcode():属性相同的对象返回值必须相同,属性不同的返回值尽量不同

        equals():属性相同返回true,属性不同返回false,返回false时存储

LinkedHashSet的概述

底层是用链表实现的,属于HashSet()派系,是set集合中唯一一个能保证怎么存就怎么取的集合对象,也是保证元素唯一的,与hashset()的原理一样

产生10个1-20之间的随机数要求随机数不能重复

import java.util.HashSet;
import java.util.Random;

public class test1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		HashSet<Integer> hs = new HashSet<>(); //存储于hashset中
		Random r = new Random();  //用random()生成随机数
		while(hs.size()<10) {  //如果集合里面存储的数字不到十个就继续存进去
			hs.add(r.nextInt(21));   //生成随机数并存进集合
		}
	//	System.out.println(hs);
		for(Integer integer : hs) {  //用增强for遍历集合
			System.out.println(integer);
		}
	}

}

练习

用Scanner从键盘读取一行输入,去掉其中重复字符,打印出不同的字符

import java.util.HashSet;
import java.util.Scanner;

public class test2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);  //创建scanner对象
		HashSet<Character> hs = new HashSet<>(); //创建hashset集合
		String line = sc.nextLine();   //输入字符串存入line中
		char[] arr = line.toCharArray();  //利用String中的方法将字符串转成字符数组
		for(int i=0;i<arr.length;i++) {   //遍历数组将数字存在集合中
			hs.add(arr[i]);
		}
		System.out.println(hs);
	}

}

将集合中的重复元素去掉

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;

public class test3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ArrayList<String> al = new ArrayList<>();  //创建集合
		al.add("a");    //添加元素
		al.add("ad");
		al.add("a");
		al.add("ad");
		al.add("a");
		al.add("ad");
		
		getSingle(al);   //创建方法去除重复
		
		System.out.println(al);   //打印集合
	}

	public  static void getSingle(List<String> al) {
		// TODO Auto-generated method stub
		LinkedHashSet<String> lhs = new LinkedHashSet<>();  //创建set集合
		for(String string : al) {    //利用增强for循环将 list集合中的东西存入set集合中,重复元素不会被存进去
			lhs.add(string);
		}
		al.clear();   //将原list集合清楚
		for(String string : lhs) {   //将set集合中的元素再添加进原集合中
			al.add(string);
		}
	}

}

TreeSet存储integer类型的元素并遍历

TreeSet集合是用来对象元素进行排序的,同时他也可以保证元素的唯一性

import java.util.TreeSet;

public class demo3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TreeSet<Integer> ts = new TreeSet<>();
		ts.add(3);
		ts.add(2);
		ts.add(1);
		ts.add(3);
		ts.add(1);
		ts.add(2);
		
		System.out.println(ts);
 	}

}

TreeSet存储自定义对象


import java.util.TreeSet;

import com.P.Person;

public class demo4 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TreeSet<Person> ts =new TreeSet<>();
		ts.add(new Person("张三",23));
		ts.add(new Person("王五",25));
		ts.add(new Person("李四",24));
		//需要在person类中实现comparable
		//当compareto方法返回0时,集合中只有一个元素
		//返回正数时,怎么存怎么取
		//返回负数时,集合会倒叙存储
		System.out.println(ts);
	}

}

底层是利用二叉树存储的

小的存储在左边(返回负数),大的存储在右边(正数),相等就不存(0)

compareto方法,在treeset集合如何存储元素取决去compareto方法的返回值

因此compareto重写应该如下

按照年龄排序

	public int compareTo(Person o) {
		// TODO Auto-generated method stub
		int num = this.age-o.age;
		return num==0 ?this.name.compareTo(o.name):num;
	}

按照姓名排序( 姓名比较的是unicode码表值

@Override
	public int compareTo(Person o) {
		// TODO Auto-generated method stub
		int num = this.name.compareTo(o.name);
		return num == 0 ? this.age - o.age :num;
	}
	

按照姓名长度排序

public int compareTo(Person o) {
    int length = this.name.length() - o.name.length();
    int num = length == 0? this.name.compareTo(o.name):length;
    return num == 0 ? this.age - o.age : num;
}

TreeSet保证元素唯一和比较器排序的原理以及代码实现

import java.util.TreeSet;



public class demo4 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TreeSet<String> ts =new TreeSet<>(new CompareByLen());  //Comparator c = new CompareByLen()
		ts.add("qw");
		ts.add("werfd");
		ts.add("as");
		//默认按照字典顺序排序
		
		System.out.println(ts);
	}

}
class CompareByLen /*extends Object*/ implements Comparator<String> {

	@Override
	public int compare(String o1, String o2) {   //按照字符串的长度比较
		int num = o1.length() - o2.length();
		return num == 0 ? o1.compareTo(o2) : num;
	}
	//由于默认继承了Object类因此相当于已经有了一个equals方法,因此实现comparator接口里面只需要重写compare
	
}

TreeSet原理

TreeSet是用来排序的,可以指定一个顺序,对象存入之后会按照指定的顺序排列

 使用方式:

        自然顺序:

                TreeSet类的add()方法中会把存入的对象提升为Comparable

                调用对象的compareTo()方法和集合中的对象比较

                根据compareTo()方法返回的结果进行存储

        比较器顺序:

                创建TreeSet的时候可以制定一个Comparator

                如果传入了Comparator的子类对象,那么TreeSet就会按照比较器中的顺序排序

                add()方法内部会自动调用Comparator接口中的compare()方法排序

        两种方式的区别:

                TreeSet构造函数什么都不传,默认按照类中Comparable的顺序(没有就报错classCastException

                TreeSet如果传入comparator就优先comparator

练习

输入几个字符串,其中有重复字符串,使其按照字典顺序输出

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

public class dd {

    /*
     * 定义list集合存储
     * 定义方法对其排序
     * 打印list集合
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ArrayList<String> ts = new ArrayList<>();
        ts.add("aaa");
        ts.add("aaa");
        ts.add("aaa");
        ts.add("gvhc");
        ts.add("xnc");
        ts.add("ach");

        sort(ts);

       for(Character c : al){
            System.out.print(c);
        }
    }
    public static void sort(List<String> list){
        //本身具有排序功能但是会去除重复,因此需要使用比较器
        TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {  //匿名内部类
            @Override
            public int compare(String s1, String s2) {
                int num = s1.compareTo(s2);
                return num == 0 ? 1 :num;
            }
        });
        ts.addAll(list);
        list.clear();
        list.addAll(ts);

    }
}

键盘接收一个字符串,程序对其所有的字符进行排序,例如键盘输入:helloitcast程序打印acehillostt

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

public class test2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        char[] arr = s.toCharArray();
        ArrayList<Character> al = new ArrayList<>();
        for(char c :arr){
            al.add(c);
        }

        sort(al);

        System.out.println(al);
    }
    public static void sort(ArrayList<Character> list){
        TreeSet<Character> ts = new TreeSet<>(new Comparator<Character>() {
            @Override
            public int compare(Character o1, Character o2) {
                int num = o1.compareTo(o2);
                return num == 0 ? 1 :num ;
            }
        });
        ts.addAll(list);
        list.clear();
        list.addAll(ts);
    }
}

 程序启动后,可以从键盘输入接收多个整数,知道输入quit时输入结束,把所有输入的整数倒序排列打印

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

public class test3 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        TreeSet<Integer> ts = new TreeSet<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                int num = o1.compareTo(o2);
                return num == 0 ? 1 : num;
            }
        });
        while(true) {
            String s = sc.nextLine();
            if(s.equals("quit")){
                break;
            }
            else {
                Integer i = Integer.parseInt(s);
                ts.add(i);
            }
        }
        for(Integer i :ts){
            System.out.println(i);
        }


    }
}

 键盘录入五个学生信息按照总分排序后输出在控制台

import student.Student;

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

public class test4 {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入学生的成绩");
        TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int num = o1.getScore()-o2.getScore();
                return num == 0 ? 1 :num;
            }
        });
        while(ts.size() < 5) {
            String s =sc.nextLine();
            String[] arr = s.split(",");
            int age = Integer.parseInt(arr[1]);
            int score  = Integer.parseInt(arr[2]);
            ts.add(new Student(arr[0],age,score));
        }
        for(Student s : ts){
            System.out.println(s);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值