java day17 Set类的子类:HashSet类 TreeSet类

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/amy260231120/article/details/82971779

Set集合,无索引,不可以重复,无序(存取不一致)

字符串遍历

		HashSet<String> hs = new HashSet<>();					//创建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(hs);									//HashSet的继承体系中有重写toString方法
		System.out.println(b1);
		System.out.println(b2);
		
		for (String string : hs) {								//只要能用迭代器迭代的,就可以使用增强for循环遍历
			System.out.println(string);
		}

HashSet如何保证元素唯一性

需要重写hashCode方法和equal方法
重写后,当他们的hashCode相同时,就调用equal()方法比较,false就存,true就不存

所以要保证hashCode返回的不一样(相当于票号,如果是2个人就给2张不同的票号)
Alt+shift+S h自动生成

	/*
	 * 为什么是31?
	 * 1,31是一个质数,质数是能被1和自己本身整除的数
	 * 2,31这个数既不大也不小
	 * 3,31这个数好算,2的五次方-1,2向左移动5位
	 */
	@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;
	}
	
	public boolean equals(Object obj) {
		if (this == obj)						//调用的对象和传入的对象是同一个对象
			return true;						//直接返回true
		if (obj == null)						//传入的对象为null
			return false;						//返回false
		if (getClass() != obj.getClass())		//判断两个对象对应的字节码文件是否是同一个字节码
			return false;						//如果不是直接返回false
		Person other = (Person) obj;			//向下转型
		if (age != other.age)					//调用对象的年龄不等于传入对象的年龄
			return false;						//返回false
		if (name == null) {						//调用对象的姓名为null
			if (other.name != null)				//传入对象的姓名不为null
				return false;					//返回false
		} else if (!name.equals(other.name))	//调用对象的姓名不等于传入对象的姓名
			return false;						//返回false
		return true;							//返回true
	}

ListedHashSet类

底层是链表实现的,是set集合中唯一一个能保证怎么存就怎么取的集合对象
因为是HashSet的子类,所以也是保证元素唯一的,与HashSet的原理一样

TreeSet类

1、特点:TreeSet集合是用来对元素进行排序的,可以自定义排序方式,也可以保证元素的唯一。

  • 底层:二叉树,小的存储在左边(负数),大的存储在右边(正数),相等就不存(0)
    compareTo()方法在集合中如何存储元素取决于方法的返回值

2:使用方法:

  • 自然顺序(Comparable)
    TreeSet类的add()方法会吧存入的对象提升为Comparable类型
    滴啊用对象的compareTo()方法和集合中的对象比较
    根据compareTo()返回值进行存储
  • 比较器顺序(Comparator)
    创建TreeSet的时候可以指定一个Comparator接口
    如果传入了Comparator的子类对象,那么TreeSet就会按照比较器中的顺序排序
    add()方法内部会自动调用Comparator接口中compare方法排序
    调用的对象是compare方法的第一个参数,集合中的对象是compare方法的第二参数
  • 区别
    TreeSet的构造函数什么都不传,默认按照类中Comparable
    构造函数中传入比较器Comparator,按照比较器排序

自然排序

// 需要让Person实现Compare接口,并重写compareTo方法
// 当compareTo返回0的时候,集合中只有一个元素
// 当compareTo返回正数的时候,集合会怎么存就这么取
// 当compareTo返回负数的时候,集合会倒叙存储
		TreeSet<Person> ts = new TreeSet<>();
		ts.add(new Person("张三", 23));
		ts.add(new Person("李四", 13));
		ts.add(new Person("周七", 13));
		ts.add(new Person("王五", 43));
		ts.add(new Person("赵六", 33));
		
		System.out.println(ts);
/*@Override
	//按照年龄排序
	public int compareTo(Person o) {
		int num = this.age - o.age;				//年龄是比较的主要条件
		return num == 0 ? this.name.compareTo(o.name) : num;//姓名是比较的次要条件
	}*/

	/*@Override
	//按照姓名排序
	public int compareTo(Person o) {
		int num = this.name.compareTo(o.name);		//姓名是主要条件 string类也重写了compareTo方法
		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;						//比较年龄为次要条件
	}

比较器排序

//需求:将字符串按照长度排序
// string类的排序默认是按照字典排序
		TreeSet<String> ts = new TreeSet<>(new CompareByLen());		//Comparator c = new CompareByLen();
		ts.add("aaaaaaaa");
		ts.add("z");
		ts.add("wc");
		ts.add("nba");
		ts.add("cba");
		
		System.out.println(ts);

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

	@Override
	public int compare(String s1, String s2) {		//按照字符串的长度比较
		int num = s1.length() - s2.length();		//长度为主要条件
		return num == 0 ? s1.compareTo(s2) : num;	//内容为次要条件
	}
	
}

Test:将集合中的重复元素去掉

package com.heima.test;

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

public class Test3 {

	/**
	 *  需求:将集合中的重复元素去掉
	 *  
	 *  分析:
	 *  1,创建List集合存储若干个重复元素
	 *  2,单独定义方法去除重复
	 *  3,打印一下List集合
	 */
	public static void main(String[] args) {
		//1,创建List集合存储若干个重复元素
		ArrayList<String> list = new ArrayList<>();
		list.add("a");
		list.add("a");
		list.add("a");
		list.add("b");
		list.add("b");
		list.add("b");
		list.add("c");
		list.add("c");
		list.add("c");
		list.add("c");
		
		//2,单独定义方法去除重复
		getSingle(list);
		
		//3,打印一下List集合
		System.out.println(list);
	}
	/*
	 * 分析
	 * 去除List集合中的重复元素
	 * 1,创建一个LinkedHashSet集合
	 * 2,将List集合中所有的元素添加到LinkedHashSet集合
	 * 3,将list集合中的元素清除
	 * 4,将LinkedHashSet集合中的元素添加回List集合中
	 */
	public static void getSingle(List<String> list) {
		//1,创建一个LinkedHashSet集合
		LinkedHashSet<String> lhs = new LinkedHashSet<>();
		//2,将List集合中所有的元素添加到LinkedHashSet集合
		lhs.addAll(list);
		//3,将list集合中的元素清除
		list.clear();
		//4,将LinkedHashSet集合中的元素添加回List集合中
		list.addAll(lhs);
	}

}

package com.heima.test;

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

public class Test4 {

	/**
	 * 在一个集合中存储了无序并且重复的字符串,定义一个方法,让其有序(字典顺序),而且还不能去除重复
	 * 
	 * 分析:
	 * 1,定义一个List集合,并存储重复的无序的字符串
	 * 2,定义方法对其排序保留重复
	 * 3,打印List集合
	 */
	public static void main(String[] args) {
		//1,定义一个List集合,并存储重复的无序的字符串
		ArrayList<String> list = new ArrayList<>();
		list.add("aaa");
		list.add("aaa");
		list.add("ccc");
		list.add("ddd");
		list.add("fffffffffff");
		list.add("heima");
		list.add("itcast");
		list.add("bbbb");
		list.add("aaa");
		list.add("aaa");
		
		//2,定义方法对其排序保留重复
		sort(list);
		
		//3,打印list
		System.out.println(list);
	}
	
	/*
	 * 定义方法,排序并保留重复
	 * 分析:
	 * 1,创建TreeSet集合对象,因为String本身就具备比较功能,但是重复不会保留,所以我们用比较器
	 * 2,将list集合中所有的元素添加到TrreSet集合中,对其排序,保留重复
	 * 3,清空list集合
	 * 4,将TreeSet集合中排好序的元素添加到list中
	 */
	public static void sort(List<String> list) {
		//1,创建TreeSet集合对象,因为String本身就具备比较功能,但是重复不会保留,所以我们用比较器
		// 用匿名函数
		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);
	}

}

猜你喜欢

转载自blog.csdn.net/amy260231120/article/details/82971779
今日推荐