java中Set集合

三.Set

特点: 无序的(放入与输出的顺序不一致), 不可重复

1.HashSet

1.1基本用法

HashSet是一种哈希算法的集合

  • 数据结构: 哈希表,哈希散列表

  • 特点 :操作速度快,根据哈希算法快速定位元素的存放位置

在这里插入图片描述

HashSet<String> set = new HashSet<String>();
set.add("aaa");
set.add("bbb");
set.add("ccc");
set.add("ddd");
set.add("aaa");// 相同元素不会添加到集合中
System.out.println(set);

/**
		 * set集合 
		 * add()  size()  remove  等都有,但是没有关于填入下标的方法
		 * set集合不能用下标访问,不能使用 普通的for循环进行遍历
		 */
for (String s : set) {
    System.out.println(s);
}

// addAll  添加一个集合  ---  可以用对list集合进行去重   list集合转为 了set集合
List<String> list = Arrays.asList(new String[]{"a","b","c","d","d","a"});
set.addAll(list);
System.out.println(set);

//使用构造方法将 list转为set集合
HashSet<String> set2 = new HashSet<String>(list);
System.out.println(set2);
1.2 HashSet如何判重
  • 添加元素时,调用该对象的hashcode()方法,获取一个哈希值

  • 根据哈希值,使用哈希算法确定一个哈希表中的位置

  • 如果该位置没有元素,则直接放入

  • 如果该位置有元素了,则调用两个对象的equals方法进行比较

    true: 则认为是同一个对象,无法添加,舍弃当前对象

    false:则认为不是同一个对象,以链式结构向当前位置进行追加,改变了哈希表的结构,会影响性能。

总结:

  • 判断重复的依据,两个对象hashCode值一致,并且equals也返回true ---- 同一个对象—集合中只能添加一个进去
  • 在set集合中防止相同对象被添加,需要 hashCode 和 equals都 重写
package javaSE13_Set集合;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;

public class Test01_HashSet {
	public static void main(String[] args) {
		Test01_HashSet t = new Test01_HashSet();
//		t.test1();
		t.test2();
	}
	
	/**
	 * 基本用法
	 */
	public void test1(){
		HashSet<String> set = new HashSet<String>();
		set.add("aaa");
		set.add("bbb");
		set.add("ccc");
		set.add("ddd");
		set.add("aaa");// 相同的元素不会添加到集合中
		System.out.println(set);
		/**
		 * add()  size()  remove 等方法都有,
		 * 但 与下标相关方法都没有
		 * set集合不能有下标访问,不能使用普通循环进行遍历
		 */
		for (String s : set) {
			System.out.println(s);
		}
		// addAll() 添加一个集合  -- 可用对list集合进行去重
		List<String> list =Arrays.asList(new String[]{"a","b","c","d","a","b"});
		set.addAll(list);
		System.out.println(set);
		
		//使用构造方法 将list转为set
		HashSet< String> set2 = new HashSet<String>(list);
		System.out.println(set2);
	  
	}
	
	/**
	 * HashSet 判断重复的标准
	 */
	public void test2(){
		HashSet<Student> set = new HashSet<Student>();
		Student s1 = new Student(1001, "tom");
		Student s2 = new Student(1001, "tom");
		System.out.println(s1.equals(s2));
		System.out.println(s1.hashCode());
		System.out.println(s2.hashCode());
		set.add(s1); set.add(s2);
		System.out.println(set);
		
		/**
		 * 如果认为学号  名字都一样,就是同一个学生,只需要添加一个到集合中
		 * 需要重写eq方法 和hashCode()
		 */
		
	}
}

2.TreeSet

2.1基本用法

用于对元素排序的有序集合

  • 数据结构:二叉树
  • 特点:元素有大小顺序
2.2排序

排序:

  1. 元素会根据自然顺序排列

    存入的元素不具有自然顺序 ,集合会报错 ----- 该对象不可比较

    解决: 让元素可以比较,将要比较的对象实现一个Comparable接口,表示该类型的对象可以比较

    ​ 并且重写compareTo()方法,指定具体的比较规则

  2. 提供一个比较器,根据比较器进行排序

    定义一个比较器,就是定义一个实现了Compartor 接口的类,实现compare()方法

    在创建集合是,将比较器传入。

package javaSE13_Set集合;

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

public class Test02_TreeSet {
	public static void main(String[] args) {
		Test02_TreeSet t = new Test02_TreeSet();
//		t.test01();
		t.test02();
	}
	
	public void test01(){
		TreeSet<Integer> set = new TreeSet<Integer>();
		TreeSet<String> set2 = new TreeSet<String>();
		set.add(1);
		set.add(15);
		set.add(79);
		set.add(4);
		set.add(56);
		set.add(0);
		
		set2.add("abde");
		set2.add("fjek");
		set2.add("hueij");
		set2.add("aaeie");
		set2.add("djeju");
		System.out.println(set);
		System.out.println(set2);
	}
	public void test02(){
		//1.引用类型要能够比较大小,实现Comparable接口,并在compareTo方法中指定比较的规则
		TreeSet<User> set = new TreeSet<User>();
		set.add(new User(1, "aa", 12));
		set.add(new User(2, "bb", 15));
		set.add(new User(3, "cc", 2));
		set.add(new User(4, "dd", 15));
		set.add(new User(5, "ee", 34));
//		System.out.println(set);
		
		//2.通过比较器对set集合进行排序
//		A: 创建实现类
		/*MyComparator c = new MyComparator();//new一个比较器对象
		//set2集合的排序按照 c这个比较器对象中定义的规则排序
		TreeSet<User2> set2 = new TreeSet<User2>(c);*/
		
//		B: 直接创建的是接口,匿名内部类的写法,就不需要单独创建一个实现类
	/*	Comparator<User2> c = new Comparator<User2>(){
			//定义比较的规则
			@Override
			public int compare(User2 u1, User2 u2) {
				int i = u1.getAge() - u2.getAge();
				if(i==0){
					i=u1.getId() - u2.getId();
				}
				return i;
			}
		};
		TreeSet<User2> set2 = new TreeSet<User2>(c);*/
		
//		C: 再简化
		TreeSet<User2> set2 = new TreeSet<User2>(new Comparator<User2>() {
			@Override
			public int compare(User2 u1, User2 u2) {
				int i = u1.getAge() - u2.getAge();
				if(i==0){
					i=u1.getId() - u2.getId();
				}
				return i;
			}
		});
		set2.add(new User2(1, "aa", 12));
		set2.add(new User2(2, "bb", 15));
		set2.add(new User2(3, "cc", 2));
		set2.add(new User2(4, "dd", 15));
		set2.add(new User2(5, "ee", 34));
		System.out.println(set2);
	}
}

package javaSE13_Set集合;

import java.util.Comparator;
/**
 * 是一个比较器 : 就是一个实现了Comparator接口的类
 * @author wenwen
 *
 */
public class MyComparator implements Comparator<User2>{
	//定义比较的规则
	@Override
	public int compare(User2 u1, User2 u2) {
		int i = u1.getAge() - u2.getAge();
		if(i==0){
			i=u1.getId() - u2.getId();
		}
		return i;
	}

}

注意:TreeSet判断重复的依据: 但添加的两个元素的compareTo() 或者 是 compare()方法 返回0时,就认为两个对象相同了,只会添加一个到集合中

package javaSE13_Set集合;

public class User implements Comparable<User>{
	private int id;
	private String name;
	private int age;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	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;
	}
	public User() {
		super();
		// TODO Auto-generated constructor stub
	}
	public User(int id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", age=" + age + "]\n";
	}
	
	
	/**
	 *  自定义比较的规则
	 *  如果 按照 从小到大的顺序
	 *  负数: 小于
	 *  0: 等于
	 *  正数:this 为 大于
	 */
	/*@Override
	public int compareTo(User o) {
		//根据年龄进行比较     如果年龄相同 则继续按照另一个属性排序
		if(this.age>o.getAge()){// this.age-o.getAge  是个正数
			return 1;
		}else if(this.age < o.getAge()){
			return -1;
		}else{
			//年龄相同,id继续排
			if(this.id > o.getId()){
				return 1;
			}else if(this.id<o.getId()){
				return -1;
			}else{
				//如果 id继续相等,按照 姓名排
				// 如果 比较的是字符串,直接调用字符串的比较方法
				return this.name.compareTo(o.getName());
			}
		}
	}*/
	@Override
	public int compareTo(User o) {
		int i = this.age - o.getAge();
		if(i==0){
			i=this.id - o.getId();
			if(i==0){
				i=this.name.compareTo(o.getName());
			}
		}
		return i;
	}
}
package javaSE13_Set集合;

public class User2 {
	private int id;
	private String name;
	private int age;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	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;
	}
	public User2() {
		super();
		// TODO Auto-generated constructor stub
	}
	public User2(int id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", age=" + age + "]\n";
	}
}

JavaSet是一种集合类型,它不允许重复元素,并且没有固定的顺序。常见的Set实现类有HashSet、LinkedHashSet和TreeSet。下面是Set的用法示例: 1. 创建Set对象 可以使用以下语法创建Set对象: ```java Set<T> set = new HashSet<>(); // 创建HashSet对象 Set<T> set = new LinkedHashSet<>(); // 创建LinkedHashSet对象 Set<T> set = new TreeSet<>(); // 创建TreeSet对象 ``` 其,T表示元素的类型。 2. 添加元素 可以使用add()方法向Set添加元素: ```java set.add(element); // 将元素添加到Set,如果Set已经存在该元素,add()方法不会执行任何操作 ``` 3. 删除元素 可以使用remove()方法从Set删除元素: ```java set.remove(element); // 从Set删除指定元素,如果Set不存在该元素,remove()方法不会执行任何操作 ``` 4. 判断元素是否存在 可以使用contains()方法判断Set是否存在指定元素: ```java set.contains(element); // 如果Set存在该元素,返回true;否则返回false ``` 5. 遍历元素 可以使用foreach循环或者迭代器遍历Set的元素: ```java for (T element : set) { // 对元素进行操作 } Iterator<T> iterator = set.iterator(); while (iterator.hasNext()) { T element = iterator.next(); // 对元素进行操作 } ``` 6. 获取元素个数 可以使用size()方法获取Set元素的个数: ```java set.size(); // 返回Set元素的个数 ``` 7. 清空Set 可以使用clear()方法清空Set的所有元素: ```java set.clear(); // 清空Set的所有元素 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值