学习Java第二十五天--集合框架之--Set集合

Set接口的特点、方法、实现类的用法、注意事项、代码练习

12.4 Set集合

12.4.1 Set子接口

  • 特点:无序、无下标、元素不可重复
  • 方法:全部继承自Collection中的方法

12.1.2 Set实现类

  • HashSet【重点】
    基于HashCode实现元素不重复;
    先判断hashCode是否一致,当存入元素的哈希码相同时,会调用equals进行确认,如果结果为true,则拒绝后者存入;
    HashSet的底层使用的HashMap类,即是将所有需要存入HashSet的值,直接保存在HashMap中;
    foreach循环:
    for(数据类型 变量名 : 容器名称){//可遍历集合或数组(常用在无序集合)
    //逻辑代码
    }
import java.util.HashSet;

public class TestHashSet {

	public static void main(String[] args) {
		
		HashSet<String> set = new HashSet<String>();
		
		set.add("A");
		set.add("B");
		set.add("C");
		set.add("D");
		
		System.out.println(set.size());
		
		set.remove("C");
		
		System.out.println(set.size());
		
		System.out.println(set);
		
		//如何获取Set中的元素?
		//遍历方式发生改变:foreach循环
		for( String s : set ) {
			System.out.print(s +"\t");
		}
		
	}

}

输出结果:

4
3
[A, B, D]
A	B	D	
import java.util.HashSet;
import java.util.Set;

public class TestHashSet2 {

	public static void main(String[] args) {
		
		Set<Integer> numbers = new HashSet<Integer>();
		
		System.out.println(numbers.add(11));
		numbers.add(22);
		numbers.add(33);
		numbers.add(44);
		numbers.add(55);
		numbers.add(66);
		numbers.add(77);
		numbers.add(88);
		numbers.add(99);
		
		System.out.println(numbers.add(11));//重复的无法插入
		
		for (Integer i : numbers) {
			System.out.print(i + "\t");
		}
		System.out.println();
		
		  
	}

}

输出结果:

true
false
33	66	99	22	55	88	11	44	77	
import java.util.HashSet;
import java.util.Set;

public class TestHashSet3 {

	public static void main(String[] args) {
		
		Student s1 = new Student("Tom" , 18 , "male" , 99D);
		Student s2 = new Student("Jack" , 20 , "male" , 97D);
		Student s3 = new Student("Michael" , 21 , "male" , 98D);
		Student s4 = new Student("Rose" , 19 , "female" , 100D);
		Student s5 = new Student("Tom" , 18 , "male" , 99D);//与s1内容相同,但地址不同,可以插入,需要去掉重复
															//通过覆盖equals方法实现
		Set<Student> students = new HashSet<Student>();

		students.add(s1);
		students.add(s2);
		students.add(s3);
		students.add(s4);
		students.add(s1);//去掉了重复 equals--->Object提供的equals方法,内部使用this==obj进行判断
		students.add(s5);
		
		//注意:HashSet没有必要在每次插入新值是=时,都去与已有数据进行一一比较
		//注意:HashSet使用equals方法进行比较,是有前提的(两个对象的哈希码相同)
		
		for (Student student : students) {
			System.out.println(student.toString());
		}
	}

}
class Student{
	String name;
	Integer age;
	String sex;
	Double score;
	
	public Student() {}
	
	public Student(String name, Integer age, String sex, Double score) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.score = score;
	}
	
	
	//hashCode才是调用equals方法的前提
	//只有当两个对象的哈希码相同时,才有必要调用equals方法
	@Override
	public int hashCode() {
		int result = 0 ;
		result = this.name.hashCode() + this.age.hashCode() + this.sex.hashCode() + this.score.hashCode();
		return result;
	}

	

	@Override
	public boolean equals(Object obj) {//重写equals方法,以完成比较
		System.out.println("Studnet's equals()");//显示equals方法的调用情况
		if(this == obj) {
			return true;
		}
		if(obj == null) {
			return false;
		}
		if(this.getClass() != obj.getClass()) {
			return false;
		}
		Student s = (Student)obj;
		
		if( this.name.equals(s.name) && this.age.equals(s.age) && this.sex.equals(s.sex) && this.score.equals(s.score)) {
			return true;
		}
		return false;
	}


	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", sex=" + sex + ", score=" + score + "]";
	}

}

输出结果:

Studnet's equals()
Student [name=Michael, age=21, sex=male, score=98.0]
Student [name=Tom, age=18, sex=male, score=99.0]
Student [name=Jack, age=20, sex=male, score=97.0]
Student [name=Rose, age=19, sex=female, score=100.0]
  • LinkedHashSet:
    链表实现的HashSet,按照链表进行存储,即可保留演示的插入顺序;
    底层使用LinkedHashMap(链表结构)存储,节点的形式完成单独存储数据,并指向下一个节点,通过顺序访问节点,可保留元素的插入顺序;
import java.util.LinkedHashSet;

public class TestLinkedHashSet {

	public static void main(String[] args) {
		
		LinkedHashSet<Integer> numbers = new LinkedHashSet<Integer>();
		//底层使用LinkedHashMap(链表结构)存储,节点的形式完成单独数据的保存,并指向下一个节点,
		//通过顺序访问节点,可保留元素的插入顺序
		
		
		System.out.println(numbers.add(11));
		numbers.add(22);
		numbers.add(33);
		numbers.add(44);
		numbers.add(55);
		numbers.add(66);
		numbers.add(77);
		numbers.add(88);
		numbers.add(99);
		
		System.out.println(numbers.add(11));//重复的将无法插入
		
		for (Integer i : numbers) {
			System.out.print(i + "\t");
		}
		System.out.println();
	}

}

输出结果:

true
false
11	22	33	44	55	66	77	88	99	
  • TreeSet:
    基于排列顺序实现元素不重复;
    实现了SortedSet接口,对集合元素自动排序;
    元素对象的类型必须实现Comparable接口,指定排序规则;
    通过CompareTo方法确定是否为重复元素,方法返回0做为去重的依据;
import java.util.TreeSet;

public class TestTreeSet {

	public static void main(String[] args) {
		
		TreeSet<Integer> nums = new TreeSet<Integer>();
		
		nums.add(1);
		nums.add(4);
		nums.add(6);
		nums.add(5);
		nums.add(3);
		
		System.out.println(nums.add(3));//保证元素不重复(唯一)
		//CompareTo方法返回0,表示重复
		
		for (Integer integer : nums) {
			System.out.print(integer +"\t");
		}
		System.out.println();
		
		nums.add(2);
		for (Integer integer : nums) {
			System.out.print(integer +"\t");
		}
		System.out.println();
	}

}

输出结果:

false
1	3	4	5	6	
1	2	3	4	5	6	
import java.util.TreeSet;

public class TestTreeSet2 {

	public static void main(String[] args) {
		
		TreeSet<Student2> students = new TreeSet<Student2>();
		
		students.add( new Student2("Tom" , 20 , "male" , 99D) );
		students.add( new Student2("Jack" , 23 , "male" , 92D) );
		students.add( new Student2("Anine" , 21 , "female" , 100D) );
		students.add( new Student2("Rose" , 19 , "female" , 95D) );
		
		students.add( new Student2("Alex" , 22 , "male" , 100D) );//成绩重复,插入失败
		
		for (Student2 s : students) {//实现Comparable接口才能排序,且自定义排序规则
			System.out.println(s.toString());
		}
		
	}

}

class Student2 implements Comparable<Student2>{
	String name;
	Integer age;
	String sex;
	Double score;
	public Student2(String name, Integer age, String sex, Double score) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.score = score;
	}
	
	@Override
	public int compareTo(Student2 o) {//降序
		if(o.score > this.score) {//this小,就靠后
			return 1;
		}else if(o.score < this.score){
			return -1;
		}
		return 0;
	}

	@Override
	public String toString() {
		return "Student2 [name=" + name + ", age=" + age + ", sex=" + sex + ", score=" + score + "]";
	}
	
}

输出结果:

Student2 [name=Anine, age=21, sex=female, score=100.0]
Student2 [name=Tom, age=20, sex=male, score=99.0]
Student2 [name=Rose, age=19, sex=female, score=95.0]
Student2 [name=Jack, age=23, sex=male, score=92.0]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值