Set-TreeSet-HashSet-LinkedHashSet

一.Set

1.Set集合继承自Collection集合,底层数据结构是一个哈希表,能保证元素是唯一的,元素不重复!它通过它的子实现类HashSet集合去实例化,HashSet集合底层是HashMap集合的实例!
package day_15_11_12.set;

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

public class SetDemo {

	public static void main(String[] args) {
		// 创建Set集合对象
		Set<String> set = new HashSet<String>() ;
		
		//添加元素
		set.add("travel");
		set.add("you") ;
		set.add("money") ;
		set.add("need") ;
		set.add("money") ;
		set.add("you") ;
		
		//增强for遍历
		for(String s :set){
			System.out.println(s);
		}
	}
}
2.HashSet
此类实现Set接口,由哈希表(实际上是一个 HashMap 实例)支持。不保证Set的迭代顺序,尤其是不保证该顺序恒久不变。
HashSet集合的add()方法,底层是依赖于双列集合HashMap<K,V>的put(K key,V value)来实现的
put(K key,V value): 底层又依赖于HashCode()和equals()方法,传递添加元素的时候,首先判断的是 每一个元素对应的HashCode值是否一样,如果HashCode值一样,还比较他们的equals()方法,集合存储的是String类型,String类型本身重写了equals()方法,所以,默认比较的是内容是否相同,如果内容相同,这里最终返回的就是第一次存储的那个元素,由这两个方法保证元素唯一性!
package day_15_11_12.hashset;

import java.util.HashSet;

public class HashSetDemo {

	public static void main(String[] args) {
		//创建HashSet集合对象
		HashSet<String> hs = new HashSet<String>();
		
		//给该集合中添加元素
		hs.add("travel");
		hs.add("need");
		hs.add("money");
		hs.add("travel");
		
		//遍历
		for(String s : hs){
			System.out.println(s);
		}
	}
}
练习:使用HashSet集合存储自定义对象并遍历
自定义对象必须重写hashCode和equals()方法:HashSet底层是依赖于这两个实现来保证元素的唯一性!
package day_15_11_12.hashset;

import java.util.HashSet;

public class HashSetDemo2 {

	public static void main(String[] args) {
		// 创建一个HashSet集合对象
		HashSet<Student> hs = new HashSet<Student>() ;
		
		//创建学生对象
		Student s1 = new Student("zhang",13);
		Student s2 = new Student("han",14);
		Student s3 = new Student("li",15);
		Student s4 = new Student("zhang",13);
		Student s5 = new Student("SI",16);
package day_15_11_12.hashset;

public class Student {
	private String name;
	private int age;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		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 int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}	
}

//给集合添加元素hs.add(s1);hs.add(s2);hs.add(s3);hs.add(s4);hs.add(s5);//增强for遍历for(Student s : hs){System.out.println(s.getName()+"---"+s.getAge());}}}

注意:List集合和Set集合的区别?

Set:元素是唯一的,无序性(存储和取出不一致)
List:元素可以重复,有序性(存储和取出一致)
3.LinkedHashSet集合
由哈希表保证元素的唯一性,由链接列表来保证元素的有序性。
package day_15_11_12.linkedhashset;

import java.util.LinkedHashSet;

public class LinkedHashSetDemo {

	public static void main(String[] args) {
		// 创建LinkedHashSet集合对象
		LinkedHashSet<String> link = new LinkedHashSet<String>();
		
		//给集合添加元素
		link.add("travel");
		link.add("need");
		link.add("money");
		link.add("travel");
		
		//遍历集合
		for(String s : link){
			System.out.println(s);
		}
	}
}
4.TreeSet集合
底层是依赖于TreeMap的实例,而TreeMap<K,V>是依赖于红黑树结构实现的
分两种:自然排序   比较器排序
两种排序的使用取决于开发者是用什么样的构造方法
练习:使用TreeSet存储Integer类型元素
package day_15_11_12.treeset;

import java.util.TreeSet;

public class TreeSetDemo2 {

	public static void main(String[] args) {
		//创建TreeSet集合对象
		//两种构造方法:public TreeSet():无参构造:根据其元素的自然顺序进行排序
		//publict TreeSet(Comparaptr<E> com)
		TreeSet<Integer> ts = new TreeSet<Integer>();
		
		//给集合添加元素
		ts.add(20);
		ts.add(18) ;
		ts.add(23) ;
		ts.add(22) ;
		ts.add(17) ;
		ts.add(24) ;
		ts.add(19) ;
		ts.add(18) ;
		ts.add(24) ;
		
		//遍历这些元素
		for(Integer i : ts){
			System.out.print(i+" ");		//17 18 19 20 22 23 24 
		}
	}
}
练习:TreeSet集合存储自定义对象并遍历
注意:自定义对象必须实现compareable接口,重写comapreTo()方法,里面的逻辑是一个排序条件:
package day_15_11_12.treeset;

import java.util.TreeSet;

/**
 * 需求:
 * 		按照学生的年龄从小到大进行排序:主要条件
 * 		对于自定义对象什么情况下保证元素是唯一的
 * 		成员变量的值相同,认为是同一个元素
 * 		主要条件给定,需要分析次要条件
 * */
public class TreeSetDemo {
	public static void main(String[] args) {
		//创建TreeSet集合对象
		TreeSet<Student> ts = new TreeSet<Student>() ;
		
		创建学生对象
		Student s1 = new Student("zhang", 28) ;
		Student s2 = new Student("li", 18) ;
		Student s3 = new Student("luo", 17) ;
		Student s4 = new Student("zhao", 16) ;
		Student s5 = new Student("wang", 19) ;
		Student s6 = new Student("zhang", 30) ;
		
		ts.add(s1);
		ts.add(s2);
		ts.add(s3);
		ts.add(s4);
		ts.add(s5);
		ts.add(s6);
		//遍历
		for(Student s : ts){
			System.out.println(s.getName()+"---"+s.getAge());
		}
		
	}
}
package day_15_11_12.treeset;

public class Student implements Comparable<Student> {
	private String name;
	private int age;
	
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Student(String name, int age) {
		super();
		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 int compareTo(Student s) {
		// TODO Auto-generated method stub
		//return 0;
		//主要条件:按照学生的年龄从小到大进行排序
		int num =s.age - this.age ;//年龄从大到小 
		//次要条件:姓名的内容进行排序
		int num2 = num==0 ? this.name.compareTo(s.name): num ;
		return num2 ;
	}	
}

TreeSet集合的比较器排序:

public TreeSet(Comparator<E> comparator)
需求:按照学生姓名长度从小到大进行排序
两种方式实现比较器排序:
1)自定义一个类,类实现Comparator接口,作为子实现类
2)可以使用接口的匿名内部类来实现:开发中,由于减少代码书写量,不需要自定义接口的子实现类,直接这种格式!
方式一:
package day_15_11_12.treeset2;

import java.util.Comparator;

public class MyComparator implements Comparator<Student> {

	@Override
	public int compare(Student s1,Student s2) {
		//return 0;
		
		//按照学生姓名长度从小到大进行排序
		int num = s1.getName().length() - s2.getName().length() ;
		//次要条件:姓名长度一样,还要比较姓名的内容是否一样
		int num2 = num==0 ? s1.getName().compareTo(s2.getName()): num ;
		
		//姓名长度和内容都一样,还需比较两个人的年龄是否一样
		int num3 = num2 ==0 ? s1.getAge() - s2.getAge() : num2 ;
		
		return num3 ;
	}
	
}
package day_15_11_12.treeset2;

import java.util.TreeSet;

import day_15_11_12.treeset2.Student;

//方式1:自定义一个类,类实现Comparator接口,作为子实现类
public class TreeSetDemo {

	public static void main(String[] args) {
		// 创建TreeSet集合对象
		TreeSet<Student> ts = new TreeSet<Student>(new MyComparator()) ;
		
		//创建学生对象
		Student s1 = new Student("zhang", 28) ;
		Student s2 = new Student("li", 18) ;
		Student s3 = new Student("luo", 17) ;
		Student s4 = new Student("zhao", 16) ;
		Student s5 = new Student("wang", 19) ;
		Student s6 = new Student("zhang", 30) ;
		
		ts.add(s1);
		ts.add(s2);
		ts.add(s3);
		ts.add(s4);
		ts.add(s5);
		ts.add(s6);
		//遍历
		for(Student s : ts){
			System.out.println(s.getName()+"---"+s.getAge());
		}

	}

}
package day_15_11_12.treeset2;

public class Student {
	private String name;
	private int age;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		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;
	}
	
}
方式二:
package day_15_11_12.treeset2;

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

//方式2:可以使用接口的匿名内部类来实现:
public class TreeSetDemo2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>(){
			@Override
			public int compare(Student s1, Student s2) {
				//return 0;
				
				int num = s1.getName().length() - s2.getName().length() ;
				//次要条件:姓名长度一样,还要比较姓名的内容是否一样
				int num2 = num==0 ? s1.getName().compareTo(s2.getName()): num ;
				
				//姓名长度和内容都一样,还需比较两个人的年龄是否一样
				int num3 = num2 ==0 ? s1.getAge() - s2.getAge() : num2 ;
				
				return num3 ;
			}
		
		});
		
		//创建学生对象
		Student s1 = new Student("zhang", 28) ;
		Student s2 = new Student("li", 18) ;
		Student s3 = new Student("luo", 17) ;
		Student s4 = new Student("zhao", 16) ;
		Student s5 = new Student("wang", 19) ;
		Student s6 = new Student("zhang", 30) ;
		
		ts.add(s1);
		ts.add(s2);
		ts.add(s3);
		ts.add(s4);
		ts.add(s5);
		ts.add(s6);
		//遍历
		for(Student s : ts){
			System.out.println(s.getName()+"---"+s.getAge());
		}		
	}
}
package day_15_11_12.treeset2;

public class Student {
	private String name;
	private int age;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		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;
	}
	
}

练习:键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台

package day_15_11_12.treeset2;

import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
/**
 * 分析:1)创建一个学生类,提供姓名,语文,数学,英语这个成员变量
 * 	    2)创建TreeSet集合对象:TreeSet<Student>(Comparator<Student> com)
 * 		3)分析条件:主要条件:总分从高到低
 * 		    次要条件:总分相同,语文..
 * 		4)键盘录入5个学生:for循环
 * 		5)输出
 * */
public class TreeSetTest {

	public static void main(String[] args) {
		// 创建TreeSet集合对象,使用有参构造
		// 比较器排序匿名内部类的方式
		TreeSet<Student1> ts = new TreeSet<Student1>(new Comparator<Student1>() {

			@Override
			public int compare(Student1 s1, Student1 s2) {
				// 主要条件:总分从高到到第进行排序
				int num = s2.getSum() - s1.getSum();

				// 总分相同,比较语文成绩
				int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;

				// 总分相同,语文成绩相同,比较数学成绩
				int num3 = num2 == 0 ? s1.getMath() - s2.getMath() : num2;

				// 总分相同,语文成绩相同,数学相同,比较英语
				int num4 = num3 == 0 ? s1.getEnglish() - s2.getEnglish() : num3;

				// 总分以及各科成绩都相同,姓名内容是否相同
				int num5 = num4 == 0 ? s1.getName().compareTo(s2.getName()): num4;
						
				return num5;
			}
		});

		System.out.println("录入学生信息开始:");
		// 键盘录入5个学生的信息,姓名,语文成绩,数学成绩,英语成绩
		for (int x = 1; x <= 5; x++) {
			// 创建键盘录入对象
			// 为了方便录入数据,数据类型都使用String类型接收
			Scanner sc = new Scanner(System.in);
			System.out.println("请输入第" + x + "个学生的姓名:");
			String name = sc.nextLine();
			System.out.println("请输入第" + x + "个学生的语文成绩:");
			String chineseString = sc.nextLine();
			System.out.println("请输入第" + x + "个学生的数学成绩:");
			String mathString = sc.nextLine();
			System.out.println("请输入第" + x + "个学生的英语成绩:");
			String englishString = sc.nextLine();

			// 创建一个学生对象,把这些信息封装到学生对象中
			Student1 s = new Student1();
			s.setName(name);
			s.setChinese(Integer.parseInt(chineseString));
			s.setMath(Integer.parseInt(mathString));
			s.setEnglish(Integer.parseInt(englishString));

			// 将学生对象添加到集合中
			ts.add(s);
		}

		System.out.println("学生信息录入结束:");
		System.out.println("学生信息总分从高到底排列数学如下:");
		System.out.println("姓名\t语文成绩\t数学成绩\t英语成绩");

		// 增强for遍历集合
		for (Student1 s : ts) {
			System.out.println(s.getName() + "\t" + s.getChinese() + "\t"
					+ s.getMath() + "\t" + s.getEnglish());
		}

	}

}
package day_15_11_12.treeset2;

public class Student1 {
	private String name ;//姓名
	private int chinese ;//语文
	private int math ;//数学
	private int english;//英语
	public Student1() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student1(String name, int chinese, int math, int english) {
		super();
		this.name = name;
		this.chinese = chinese;
		this.math = math;
		this.english = english;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	public int getChinese() {
		return chinese;
	}
	public void setChinese(int chinese) {
		this.chinese = chinese;
	}
	public int getMath() {
		return math;
	}
	public void setMath(int math) {
		this.math = math;
	}
	public int getEnglish() {
		return english;
	}
	public void setEnglish(int english) {
		this.english = english;
	}
	
	
	//总分的方法
	public int getSum(){
		return this.chinese + this.math+this.english ;
	}
}







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值