天天看點

集合架構之set集合

概念:

set存儲的元素是無序的,不可重複無序性不等于随機性,

添加set所在類必須重寫equals和hashCode方法。

保證set的不可重複性,set元素中的存儲采用了雜湊演算法。

集合架構之set集合
集合架構之set集合
  •  由此論證set集合不能存放重複元素

2.Hash哈希存儲,重複元素存儲底層

list.contains  底層調用eqluals方法

set.add  底層調用hashcode/equals

public class Demo1 {
 
	public static void main(String[] args) {
		Set<Object>set=new HashSet<>();
		set.add(new Student("小小",12));
		set.add(new Student("大大",22));
		set.add(new Student("小%小",13));
		set.add(new Student("小小",12));
		System.out.println(set.size());
		for (Object o: set) {
			System.out.println(o);
		}
		System.out.println("=============");
		Iterator<Object>it=set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
	
}
class Student{
	private String name;
	private int 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;
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	public Student() {
		// TODO Auto-generated constructor stub
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", 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;
	}
           
集合架構之set集合
  •  set集合中的元素是無序的(存入和取出的順序不一定一緻)
  • set重複隻限于對字元串,八大基本資料類型

但equals和hashCode同時運作

集合架構之set集合
集合架構之set集合

 結論:是用hsahcode和equals方法完成

如果hashcode值相同,才會判斷equals是否為true;如果hashcode值不同,那麼不會調用equals.

2.集合架構TreeSet(自然排序,比較器排序)

2.1自然排序

public class Test {
	public static void main(String[] args) {
		Set<Object>set=new HashSet<>();
		set.add("ab");
		set.add("bc");
		set.add("cf");
		set.add("cd");
      System.out.println(set);
		
	}
}
           

運作結果:

集合架構之set集合
package com.pengjianglin.list;

import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

public class Demo1 {
 
	public static void main(String[] args) {
		Set<Student>set=new TreeSet<>(new Comparator() {//内部内
			@Override
			public int compare(Object o1, Object o2) {
				return ((Student) o1).getAge()-((Student) o2).getAge();
			}
		});
		
		set.add(new Student("小小",12));
		set.add(new Student("大大",22));
		set.add(new Student("小%小",13));
		set.add(new Student("小小",12));
		System.out.println(set.size());
		Iterator<Student>it=set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
	
}
/**
 * 按照年齡升序的規則
 * @author zjjt
 *
 */
//class ageAsc implements Comparator<Student>{
//
//	@Override
//	public int compare(Student o1, Student o2) {
//		// TODO Auto-generated method stub
//		return o1.getAge()-o2.getAge();
//	}
//	
//}
	

class Student{
	private String name;
	private int 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;
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	public Student() {
		// TODO Auto-generated constructor stub
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	@Override
	public int hashCode() {
		System.out.println("hashcode--------"+this.name);
		int code=this.name.hashCode()+this.age;//算一個name和age的哈希碼值的和
		System.out.println(code);
		return code;
	}
	@Override
	public boolean equals(Object obj) {
		System.out.println("equals---------");
		Student s=(Student)obj;
		return this.name.equals(s.name)&&this.age==s.age;
	}
	
	
}
	
           

運作結果:

集合架構之set集合

注:我們存放的是亂碼,取出來的時候是進行了排序(以上是根據年齡來升序)

我們引用資料類型想要排序,必須實作Comparable接口,否則會出現報錯,如下:

public static void main(String[] args) {
		Set<Student>set=new TreeSet<>();
		
		set.add(new Student("小小",12));
		set.add(new Student("大大",22));
		set.add(new Student("小%小",13));
		set.add(new Student("小小",12));
		System.out.println(set.size());
		Iterator<Student>it=set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
           
集合架構之set集合

總結:比較器排序用于應對某些代碼頻繁修改所帶來的的不便時通過實作comparator來完成(調用不同的方法)不需要每次都修改代碼