Set接口,HashSet类,TreeSet,LinkedHashSet类

Set接口

特点:
1.唯一
2.无序
3.可以存储null值,但是null值不能重复
package com.sxt.setdemo;

import java.util.HashSet;
import java.util.Set;

public class SetDemo01 {
	public static void main(String[] args) {
		Set<String> set = new HashSet<>();
		set.add("abc");
		set.add("efg");
		set.add("abc");
		set.add("hij");
		set.add("abc");
		set.add(null);
		set.add(null);
		
		System.out.println(set);
	}

}

HashSet类

HashSet类
  
  特点:
  	此类实现Set接口,由哈希表(实际为HashMap实例)支持。
   对集合的迭代次序不作任何保证; 
   特别是,它不能保证订单在一段时间内保持不变。 这个类允许null元素
   
   1.底层数据结构是哈希表结构,底层是通过HashMap实现
   2.无序
   3.允许null值
   4.唯一
  
  哈希算法原理:
  	1.哈希算法和对象本身有关
	2.哈希算法和对象本身的hashCode有关
		hashCode在没有重写hashCode方法的情况下就是地址值的一个转换值,可以理解为地址值
	3.尽量保证哈希值唯一,但是不能绝对保证
  哈希表结构原理:
  	哈希表结构如何保证元素无序的? 依赖的是随机的哈希算法产生的索引
  	哈希表结构如何保证元素唯一的? 依赖的是hashCode和equals方法
   过程是:
   	首先比较两个元素的hashCode是否相等
   		相等
   			比较两个元素的equals方法是否相等
   			相等
   				表示同一个元素,就不存储的集合中
   			不相等
   				表示不是同一个元素,存储到集合中
   		不相等
   			说明两个元素不相等,直接存储
package com.
sxt.hashsetdemo;

import java.util.HashSet;

public class HashSetDemo01 {
	public static void main(String[] args) {
		HashSet<String> hs = new HashSet<String>();
		hs.add("ab");
		hs.add("ac");
		hs.add("bc");
		hs.add("ba");
		hs.add("ba");
		
		for (String s : hs) {
			System.out.println(s);
		}
	}
}

随机获取6个20~30之间的数

package com.sxt.hashsetdemo;

import java.util.HashSet;

public class HashSetDemo01 {

	public static void main(String[] args) {
		HashSet<Integer> hs = new HashSet<Integer>();
		while (hs.size() < 6) {
			hs.add(getRandomNum(20, 30));
		}
		for (Integer integer : hs) {
			System.out.println(integer);
		}
	}
	public static int getRandomNum(int start, int end) {
		
		return (int) (Math.random() * (end - start + 1) + start);
	}

}

TreeSet

特点:
	1.可排序
	2.唯一
	3.底层数据结构是二叉树
package com.sxt.treesetdemo;

import java.util.TreeSet;

/*
 * TreeSet
 * 
 * 特点:
 * 	1.可排序
 *  2.唯一
 *  3.底层数据结构是二叉树
 * 
 * Integer
 */
public class TreeSetDemo01 {
	public static void main(String[] args) {
		TreeSet<Integer> ts = new TreeSet<>();
		ts.add(30);
		ts.add(40);
		ts.add(15);
		ts.add(60);
		ts.add(28);
		ts.add(30);
		ts.add(30);
		ts.add(30);
		for (Integer integer : ts) {
			System.out.println(integer);
		}
	}
}

使用TreeSet存储学生对象
自然排序

package com.sxt.treesetdemo;

import java.util.TreeSet;

/*
 * 使用TreeSet存储学生对象
 * 
 * com.sxt.treesetdemo.Student cannot be cast to java.lang.Comparable
 * 
 * public static int compare(int x, int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }
 */
public class TreeSetDemo02 {
	public static void main(String[] args) {
		TreeSet<Student> ts = new TreeSet<>();
		ts.add(new Student("zhangsan", 18));
		ts.add(new Student("lisi", 20));
		ts.add(new Student("wangwu", 30));
		ts.add(new Student("haha", 30));
		ts.add(new Student("hehe", 30));
		ts.add(new Student("zhaoliu", 40));
		ts.add(new Student("heihei", 30));
		ts.add(new Student("sunqi", 25));
		
		for (Student s : ts) {
			System.out.println(s);
		}
	}
}

class Student implements Comparable<Student>{
	private String name;
	private Integer age;
	public Student() {
		super();
	}
	public Student(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	
	@Override
	public int compareTo(Student s) {
		// 具体如何排序取决于需求
		// 先按照年龄排序,如果年龄相同按照姓名排序
		System.out.println("自然排序");
		Integer num = this.getAge() - s.getAge();
		// 年龄相同按照姓名排序
		// int cmp = 0;
		// if (num == 0) {
		// String name1 = this.getName();
		// String name2 = s.getName();
		// cmp = name1.compareTo(name2);
		// return cmp;
		// } else {
		// return num;
		// }
		int num2 = (num == 0) ? this.getName().compareTo(s.getName()) : num;
		return num2;
	}
}

比较器排序

package com.sxt.treesetdemo;

import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;
import java.util.TreeSet;

/*
 * 比较器排序
 * TreeSet(Comparator<? super E> comparator) 
 * 
 * 当自然排序和比较器排序同时存在的时候,比较器排序优先
 * 
 */
public class TreeSetDemo03 {
	public static void main(String[] args) {
//		TreeSet<Student> ts = new TreeSet<>(new ComparatorImpl());
		TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {

			@Override
			public int compare(Student s1, Student s2) {
//				System.out.println("匿名内部类比较器排序方式");
				Collator collator = Collator.getInstance(Locale.CHINA);
				int num1 = s1.getAge() - s2.getAge();
				int num2 = (num1 == 0) ? collator.compare(s1.getName(), s2.getName()) : num1;
				return num2;
			}
		});
		ts.add(new Student("张三", 18));
		ts.add(new Student("李四", 20));
		ts.add(new Student("王五", 30));
		ts.add(new Student("哈哈", 30));
		ts.add(new Student("呵呵", 30));
		ts.add(new Student("赵六", 40));
		ts.add(new Student("嘿嘿", 30));
		ts.add(new Student("孙七", 25));
		
		for (Student s : ts) {
			System.out.println(s);
		}
	}
}

class ComparatorImpl implements Comparator<Student> {

	@Override
	public int compare(Student s1, Student s2) {
		System.out.println("比较器排序");
		int num1 = s1.getAge() - s2.getAge();
		int num2 = (num1 == 0) ? s1.getName().compareTo(s2.getName()) : num1;
		return num2;
	}
	
}
2.键盘录入5个学生信息(姓名,年龄,语文成绩,数学成绩,英语成绩),
按照总分从高到低输出到控制台
	注:总分相同等情况下按照语文成绩排序,
	其次是数学成绩、英语成绩、年龄、姓名

一个固定排序模板

package com.sxt.practice;

import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;
import java.util.TreeSet;

import com.sxt.treesetdemo.RandomValue;

public class TreeSetDemo04 {
	public static void main(String[] args) {
		TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {

			@Override
			public int compare(Student s1, Student s2) {
				// 固定模板
				Collator c = Collator.getInstance(Locale.CHINA);
				double cmp = s1.getTotalScore() - s2.getTotalScore();
				double cmp2 = (cmp == 0) ? (s1.getChineseScore() - s2.getChineseScore()) : cmp;
				double cmp3 = (cmp2 == 0) ? (s1.getMathScore() - s2.getMathScore()) : cmp2;
				double cmp4 = (cmp3 == 0) ? (s1.getEnglishScore() - s2.getEnglishScore()) : cmp3;
				double cmp5 = (cmp4 == 0) ? (s1.getAge() - s2.getAge()) : cmp4;
				double cmp6 = (cmp5 == 0) ? (c.compare(s1.getName(), s2.getName())) : cmp5;
				return (cmp6 < 0) ? -1 : ( (cmp6 == 0) ? 0 : 1 ); 
			}
		});
		for (int i = 0; i < 10; i++) {
			String name = RandomValue.getChineseName();
			int age = RandomValue.getRandomNum(18, 20);
			double chineseScore = RandomValue.getRandomNum(88, 89);
			double mathScore = RandomValue.getRandomNum(90, 91);
			double englishScore = RandomValue.getRandomNum(95, 96);
			
			Student s = new Student(name, age, chineseScore, mathScore, englishScore);
			ts.add(s);
		}
		
		for (Student s : ts) {
			System.out.println(s.getTotalScore() + " | " + s.getChineseScore()
				+ " | " + s.getMathScore() + " | " + s.getEnglishScore()  
				+ " | " + s.getAge()  + " | " +  s.getName());
		}

	}
	

}

class Student {
	private String name;
	private Integer age;
	private Double chineseScore;
	private Double mathScore;
	private Double englishScore;
	public Student() {
		super();
	}
	public Student(String name, Integer age, Double chineseScore, Double mathScore, Double englishScore) {
		super();
		this.name = name;
		this.age = age;
		this.chineseScore = chineseScore;
		this.mathScore = mathScore;
		this.englishScore = englishScore;
	}
	
	//计算总成绩
	public Double getTotalScore() {
		return chineseScore + mathScore + englishScore;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public Double getChineseScore() {
		return chineseScore;
	}
	public void setChineseScore(Double chineseScore) {
		this.chineseScore = chineseScore;
	}
	public Double getMathScore() {
		return mathScore;
	}
	public void setMathScore(Double mathScore) {
		this.mathScore = mathScore;
	}
	public Double getEnglishScore() {
		return englishScore;
	}
	public void setEnglishScore(Double englishScore) {
		this.englishScore = englishScore;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", chineseScore=" + chineseScore + ", mathScore=" + mathScore
				+ ", englishScore=" + englishScore + ", getTotalScore()=" + getTotalScore() + "]";
	}
	
	
	
	
	
}

LinkedHashSet类

特点: 
	底层数据结构是哈希表和链表
	链表保证元素有序
	哈希表保证元素唯一
package com.sxt.linkedhashsetdemo;

import java.util.LinkedHashSet;
public class LinkedHashSetDemo {
	public static void main(String[] args) {
		LinkedHashSet<String> lhs = new LinkedHashSet<>();
		lhs.add("abc");
		lhs.add("abc");
		lhs.add("efg");
		lhs.add("abc");
		lhs.add("hij");
		lhs.add("abc");
		lhs.add("opq");
		
		for (String s : lhs) {
			System.out.println(s);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_42539533/article/details/87388671