(十八)Collection集合之Set集合:HashSet、TreeSet

学习内容

(一)List集合

(二)Set集合

  1. HashSet:
    • ) HashSet存储字符串并遍历
    • ) 将集合中的重复元素去掉
    • )TreeSet:负数放左边 正数放右边 0覆盖

1.HashSet存储字符串并遍历

  • Set集合:不包含重复元素的集合。

  • HashSet:此类实现Set接口,由哈希表(实际为HashMap实例)支持。 对集合的迭代次序不作任何保证; 特别是,它不能保证订单在一段时间内保持不变。 这个类允许null元素。

    • 此实现不同步。
  • HashSet存储字符串并遍历

    	    Set<String> set = new HashSet<>();
    	    		
    	    set.add("lisi");
    	    set.add("lisi");
    	    set.add("wangwu");
    	    set.add("wangw1u");
    	    set.add("wang2w1u");
    	    
    	    for (String string : set) {
    	    System.out.println(string);
    	    }
    
  • 将集合中的重复元素去掉

	public static void dinict() {
		List<String> list = new ArrayList<>();
		list.add("ui");
		list.add("ui");
		list.add("ui");
		list.add("ui");
		list.add("io");
		Set<String> set = new HashSet<>();
		for (String string : list) {
			set.add(string);
		}
		for (String string : set) {
			System.out.println(string);
		}

	}

2.HashSet存储自定义对象

  • 存储自定义对象,并保证元素唯一性。
public static void setAddTest() {
	
			Set<Student> students = new HashSet<Student>();
			students.add(new Student(1, "lisi"));
			students.add(new Student(1, "lisi"));
			students.add(new Student(1, "lisi"));
	
			for (Student student : students) {
				System.out.println(student);
			}
		}
  • 重写hashCode()和equals()方法

    Set<Teacher> set = new HashSet<>();
    Teacher t1 = new Teacher("lisi",13);
    Teacher t2 = new Teacher("lisi",13)
    Teacher t3 = new Teacher("lisi"13);
    /*
    		 *  先判断hashcode
    		 *  	hashcode不一致那么就不是同一个对象
    		 *  hashcode一致
    		 *  	那么久再去调用equals
    		 *  	true 对象一样
    		 *  	false 不一样
    		 */
    set.add(t1);
    set.add(t2);
    set.add(t3);
    
    for (Teacher teacher : set) {
        System.out.println(teacher);
    }
    

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

  • 1.HashSet原理
    • 我们使用Set集合都是需要去掉重复元素的, 如果在存储的时候逐个equals()比较, 效率较低,哈希算法提高了去重复的效率, 降低了使用equals()方法的次数
    • 当HashSet调用add()方法存储对象的时候, 先调用对象的hashCode()方法得到一个哈希值, 然后在集合中查找是否有哈希值相同的对象
      • 如果没有哈希值相同的对象就直接存入集合
      • 如果有哈希值相同的对象, 就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入, true则不存
  • 2.将自定义类的对象存入HashSet去重复
    • 类中必须重写hashCode()和equals()方法
    • hashCode(): 属性相同的对象返回值必须相同, 属性不同的返回值尽量不同(提高效率)
    • equals(): 属性相同返回true, 属性不同返回false,返回false的时候存储

4.LinkedHashSet的概述和使用

  • LinkedHashSet的特点:链表定义了迭代排序,它是将元素插入集合(插入顺序 ) 的顺序 。
    • 此实现不同步。
  • LinkedHashSet的特点
    * 可以保证怎么存就怎么取
package com.briup.day18;

import java.util.LinkedHashSet;
import java.util.Set;

public class LinkedHashSetTest {
	public static void addTest() {
		Set<String> set = new LinkedHashSet<>();
		set.add("lisi");
		set.add("wangwu1");
		set.add("wangwu2");
		set.add("wangwu3");
		set.add("wangwu4");
		for (String i : set) {
			System.out.println(i);
		}
	}

	public static void main(String[] args) {
		addTest();
	}
}

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

  • 需求:编写一个程序,获取10个1至20的随机数,要求随机数不能重复。并把最终的随机数输出到控制台。
	 public static void random() {
		Random random  = new Random();
		Set<Integer> set = new HashSet<>();
		while(set.size() < 10) {
			int number = random.nextInt(20) + 1;
			set.add(number);
		}
		
		for (Integer integer : set) {
			System.out.println(integer);
		}
	}	  

6.练习

  • 使用Scanner从键盘读取一行输入,去掉其中重复字符, 打印出不同的那些
	public static void dinictCharater() {
		Scanner sc = new Scanner(System.in);
		String line = sc.nextLine();
		Set<Character> set = new HashSet<>();
		char[] cs = line.toCharArray();
		for (char c : cs) {
			set.add(c);
		}
		System.out.println(set);

	}

7.TreeSet存储Integer类型的元素并遍历

  • TreeSet存储Integer类型的元素并遍历
Set<Integer> set = new TreeSet();
		set.add(2);
		set.add(1);
		set.add(156);
		set.add(-1);
		for (Integer integer : set) {
			System.out.println(integer);
		}

8.TreeSet存储自定义对象

  • 存储Person对象

9.TreeSet保证元素唯一和自然排序的原理和图解

  • TreeSet保证元素唯一和自然排序的原理和图解
     二叉树:
     	小的存储在左边,大的存储在右边
     	负数在左边 后一个比前一个小
     	正数在右边 后一个比前一个大
     	0代表集合中只有这样一个元素
     每次先去根元素比较
     
     按照年纪排序,年纪相同按照名字排序

10.TreeSet存储自定义对象并遍历练习

  • TreeSet存储自定义对象并遍历练习1(按照姓名排序)

11.TreeSet存储自定义对象并遍历练习2

  • TreeSet存储自定义对象并遍历练习2(按照姓名的长度排序)

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

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

     // 按照字符串长度排序
     package corejava_day17.set;
     
     import java.util.Comparator;
     import java.util.TreeSet;
     
     class Com implements Comparator<String> {
     	
     	// o2 代表集合中已经有的 
     	// o1 新添加的
     	// 每次首先都会与根元素比计较
         //负数在左边 后一个比前一个小
     	//正数在右边 后一个比前一个大
     	//0代表集合中只有这样一个元素
     	@Override
     	public int compare(String o1, String o2) {
     		int num = o1.length() - o2.length();
     		return num == 0 ? o1.compareTo(o2) : num;
     	}
     	
     }
     
     
     public class LinkedListed {
     	public static void main(String[] args) {
     		TreeSet<String> set = new TreeSet<>(new Com());
     		
     		set.add("ddddddddd");
     		set.add("dd");
     		
     		System.out.println(set.toString());
     	}
     }
     
     ```
    
    

13.TreeSet原理

  • 1.特点
    • TreeSet是用来排序的, 可以指定一个顺序, 对象存入之后会按照指定的顺序排列
  • 2.使用方式
    • a.自然顺序(Comparable)
      • TreeSet类的add()方法中会把存入的对象提升为Comparable类型
      • 调用对象的compareTo()方法和集合中的对象比较
      • 根据compareTo()方法返回的结果进行存储
    • b.比较器顺序(Comparator)
      • 创建TreeSet的时候可以制定 一个Comparator
      • 如果传入了Comparator的子类对象, 那么TreeSet就会按照比较器中的顺序排序
      • add()方法内部会自动调用Comparator接口中compare()方法排序
      • 调用的对象是compare方法的第一个参数,集合中的对象是compare方法的第二个参数
    • c.两种方式的区别
      • TreeSet构造函数什么都不传, 默认按照类中Comparable的顺序(没有就报错ClassCastException)
      • TreeSet如果传入Comparator, 就优先按照Comparator
练习
  • 在一个集合中存储了无序并且重复的字符串,定义一个方法,让其有序(字典顺序),而且还不能去除重复

    package com.briup.test;
    
    import java.util.ArrayList;
    import java.util.Comparator;
    import java.util.List;
    import java.util.TreeSet;
    
    public class Test4 {
    
    	public static void main(String[] args) {
    
    		ArrayList<String> list = new ArrayList<>();
    		list.add("aaa");
    		list.add("aaa");
    		list.add("ccc");
    		list.add("ddd");
    		list.add("fffffffffff");
    		list.add("briup");
    		list.add("bbbb");
    		list.add("aaa");
    		list.add("aaa");
    		
    		
    		sort(list);
    		
    		
    		System.out.println(list);
    	}
    	
    	
    	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;					//保留重复
    			}
    		});
    		//2,将list集合中所有的元素添加到TrreSet集合中,对其排序,保留重复
    		ts.addAll(list);
    		//3,清空list集合
    		list.clear();
    		//4,将TreeSet集合中排好序的元素添加到list中
    		list.addAll(ts);
    	}
    
    }
    
    
  • 从键盘接收一个字符串, 程序对其中所有字符进行排序,例如键盘输入: helloitcast程序打印:acehillostt(保留重复)

    package com.briup.test;
    
    import java.util.Comparator;
    import java.util.Scanner;
    import java.util.TreeSet;
    
    public class Test5 {
    
    	public static void main(String[] args) {
    		
    		Scanner sc = new Scanner(System.in);
    		System.out.println("请输入一个字符串");
    		String line = sc.nextLine();
    		
    		char[] arr = line.toCharArray();
    		
    		TreeSet<Character> ts = new TreeSet<>(new Comparator<Character>() {
    
    			@Override
    			public int compare(Character c1, Character c2) {
    		
    				int num = c1.compareTo(c2);
    				return num == 0 ? 1 : num;
    			}
    		});
    		
    		
    		for(char c : arr) {
    			ts.add(c);							
    		}
    		
    		
    		for(Character c : ts) {
    			System.out.print(c);
    		}
    	}
    
    }
    
    
  • 程序启动后, 可以从键盘输入接收多个整数, 直到输入quit时结束输入. 把所有输入的整数倒序排列打印.(保留重复的)

    package com.briup.test;
    
    import java.util.Comparator;
    import java.util.Scanner;
    import java.util.TreeSet;
    
    public class Test6 {
    
    	
    	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 i1, Integer i2) {
    				int num = i2.compareTo(i1);
    				return num == 0 ? 1 : num;
    			}
    		});
    		while(true) {
    			String line = sc.nextLine();				
    			if("quit".equals(line)) {
    				break;
    			}
    			
    			Integer i = Integer.parseInt(line);
    			ts.add(i);
    		}
    		
    		
    		for (Integer integer : ts) {
    			System.out.println(integer);
    		}
    	}
    
    }
    
    

课堂作业 ​

  • 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台。(分数相同按照名字排序)

作业

  1. 从键盘获取一行输入字符串,要求去除重复字符。
    答:6.练习。
  2. 使用TreeSet和Comparator,写TreeSetTest1
    要求:对TreeSet中的元素"HashSet"、“ArrayList”、“TreeMap”、“HashMap”、“TreeSet”、"LinkedList"进行升序和倒序排列。

潘助教答案:

package jd1914.com.briup.cha02;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class TreeTest1 {
	public static void main(String[] args) {
		Set set=new TreeSet<>(new MyComparator());
		/*Set<String> set=new TreeSet<>(new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				return 0;
			}
		});*/
		set.add("HashSet");
		set.add("ArrayList");
		set.add("TreeMap");
		set.add("HashMap");
		set.add("TreeSet");
		set.add("LinkedList");
		Iterator iterator = set.iterator();
		while (iterator.hasNext()) {
			 Object next = iterator.next();
			 System.out.println(next);	
		}
		
	}
}
class MyComparator implements Comparator{

	@Override
	public int compare(Object o1, Object o2) {
		String s1=(String) o1;
		String s2=(String) o2;
		int compareTo = s1.compareTo(s2);
		//升序
		//return compareTo;
		//降序
		return -compareTo;
		//return s1.length()-s2.length();
	}

	
	
}

  1. 分析总结 HashSet,TreeSet,LinkedHashSet。
    答:潘助教答案:
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

复习

1.类与类 继承 单继承
2.接口与接口 多继承
3.类与接口 实现 多个接口

作业中复习到的

String[] userInfo = user.split(": ");//以冒号分隔,split用法
char chars = yy.charAt(i);//charAt用法
  • //length()和length的区别?
String init = ww.substring(0,1).toUpperCase();//substring和toUpperCase()用法
//Date类 年月日时分秒
public static void date1() {
		Date date = new Date();
		SimpleDateFormat ww = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
		String s = ww.format(date);
		System.out.println(s);
	}
Date date = ww.parse(line);//parse用法
Calendar c = Calendar.getInstance();//Calendar.getInstance()用法

总结

今天的内容是比较实用的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值