集合大滿貫 II

Set接口常用方法

add(E e)

確保此 collection 包含指定的元素(可選操作)。

addAll(Collection<? extends E> c)

將指定 collection 中的所有元素都添加到此 collection 中(可選操作)。

clear()

移除此 collection 中的所有元素(可選操作)。

contains(Object o)

如果此 collection 包含指定的元素,則返回true。

containsAll(Collection<?> c)

如果此 collection 包含指定 collection 中的所有元素,則返回 true。

equals(Object o)

比較此 collection 與指定對象是否相等。

isEmpty()

如果此 collection 不包含元素,則返回true。

iterator()

返回在此 collection 的元素上進行迭代的迭代器。

remove(Object o)

從此 collection 中移除指定元素的單個實例,如果存在的話(可選操作)。

removeAll(Collection<?> c)

移除此 collection 中那些也包含在指定 collection 中的所有元素(可選操作)。

retainAll(Collection<?> c)

僅保留此 collection 中那些也包含在指定 collection 的元素(可選操作)。

size()

返回此 collection 中的元素數。

toArray()

返回包含此 collection 中所有元素的數組。

set存儲特點

相對無序存儲,不可以存儲相同的元素(排重),不能通過下標訪問

set方法 代碼上機

package com.qf.day16;

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

/**
 * Set接口
 * 特點:無序,不可重複
 * @author wgy
 *
 */
public class Demo1 {
	public static void main(String[] args) {
		//創建對象
		Set<String> set=new HashSet<String>();
		//1添加
		set.add("菊花");
		set.add("枸杞");
		set.add("紅棗");
		set.add("人蔘");
		set.add("靈芝");
		set.add("枸杞");
		System.out.println("元素個數:"+set.size());
		System.out.println(set);
		//2刪除
		//2.1刪除一個
//		set.remove("靈芝");
//		System.out.println("刪除之後:"+set);
//		//2.2清空
//		set.clear();
		//3遍歷
		//3.1foreach
		System.out.println("--------增強for----------");
		for (String string : set) {
			System.out.println(string);
		}
		//3.2使用迭代器
		System.out.println("---------迭代器-------");
		Iterator<String> it=set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
		//4判斷
		System.out.println(set.contains("菊花"));
	}
}

Set常用實現類

HashSet

此類實現Set接口,存儲結構:哈希表(數組+鏈表)。它不保證set的迭代順序;特別是它不保證該順序恆久不變。此類允許使用null元素。
哈希表:數組加鏈表,既有數組的優點也有鏈表的優點。

重寫hashCode()

hashCode()是Object中的方法,每個對象的hashCode值是唯一的,所以可以理解成hashCode值表示這個對象在內存中的位置
字符串String的hashCode(),是根據內容計算的。

public int hashCode()
{
    //覆蓋hashCode的時候,最好根據他的成員屬性來返回值
	return name.hashCode() + age*3 ; 
}

重寫equals()

equals()方法是Object類中的方法,表示比較兩個對象是否相等,若不重寫相當於比較對象的地址

public boolean equals(Object obj)
{
    //類型不相同,肯定不是同一個事物
	if(!(obj instanceof Student1))	
		return false;
	Student1 p = (Student1)obj;
	//名字和年齡都相同的話,那肯定是同一個人
	return this.name.equals(p.name) && this.age == p.age;	
}

HashSet集合實現排重

1.先根據hashCode計算位置
2.再判斷equals 如果相同,重複元素
如果不同,不是重複元素 存入
if(hashCode相同並且equals相同 只能添加一個元素)
HashSet的重複依據: hashCode和equals
需要同時重寫hashCode和equals方法,實現排重。
案例:設計一個Student類,同時重寫hashCode和equals方法,檢查是否實現排重

代碼實現

public class Student {
	private String name;
	public Student(String name) {
		super();
		this.name = name;
	}
	public Student() {
		super();
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + "]";
	}
	@Override
  	//重寫equals
	public boolean equals(Object obj) {
      	//先判斷傳入的參數對象是否是Student對象,
      	//若不是直接返回false
		if(obj instanceof Student) {
          	//若是,強轉成Student對象,並比較屬性的值
			Student s = (Student) obj;
			if(this.name.equals(s.name)) {
              	 //若屬性的值相同,則返回true
				return true;
			}
		}
		return false;
	}
  	@Override
    public int hashCode(){
      	/*hashCode方法返回值是int類型,
      	所以重寫時需要找到int類型的數據返回,
      	還要保證此方法的返回值與對象的所有屬性都相關,
      	所以返回姓名屬性的字符串的長度*/
		return this.name.length();
    }
}

LinkedHashSet

LinkedHashSet類是具有可預知迭代順序(相對有序)的Set接口的哈希表和鏈接列表實現。是HashSet的子類。
存儲特點:
有序存儲,不可以存儲相同元素(排重),通過鏈表實現的集合(註定相對有序)
LinkedHashSet集合的元素排重與HashSet集合排重方法一致。
如果我們需要迭代的順序爲插入順序或者訪問順序,那麼 LinkedHashSet 是需要你首先考慮的。

TreeSet集合

TreeSet集合是可以給元素進行重新排序的一個Set接口的實現。使用元素的自然順序對元素進行排序,或者根據創建 set 時提供的Comparator進行排序,具體取決於使用的構造方法。
存儲特點:
無序存儲,排重,通過二叉樹實現的集合,可以給元素進行重新排序

TreeSet集合的元素排序[自然排序、定製排序]

自然排序
元素所屬的類需要實現java.lang.Comparable接口,並重寫compareTo方法。
compareTo方法除了可以進行排序外,還有排重的功能,但是必須在compareTo方法中對類中所有的屬性值都進行判斷,否則不比較那個屬性,排重就會忽略哪個屬性
案例:設計一個Person類,實現將Person對象添加到TreeSet集合中時,對所有的元素進行排序

public class Person implements Comparable<Person> {
	private String name;
	private int age;
	public Person() {
		super();
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", 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
  	//重寫compareTo方法,按照年齡升序,若年齡相同按照姓名降序排序
	public int compareTo(Person o) {
      	//Person中有兩個屬性,此方法中必須對name和age兩個屬性都進行比較,否則將無法正確排重
		if(this.age != o.age) {
			return this.age - o.age;//升序
		}else {
			return o.name.compareTo(this.name);
		}
	}
}

定製排序
元素需要通過java.util.Comparator接口(比較器)中的compare方法進行比較大小,並排序。
compare方法除了可以進行排序外,還有排重的功能,但是必須在compare方法中對類中所有的屬性值都進行判斷,否則不比較那個屬性,排重就會忽略哪個屬性
TreeSet集合中的無參數構造方法默認使用自然排序的方式對元素進行排序,使用TreeSet集合的定製排序時,創建集合對象不可以直接使用無參數構造方法,需要使用傳入一個Comparator比較器的構造方法創建集合對象。

public class Animal {
	private String name;
	private int age;
	@Override
	public String toString() {
		return "Animal [name=" + name + ", 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;
	}
	public Animal(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public Animal() {
		super();
	}
}
public class AnimalDemo{
    public static void main(String[]args){
      	//創建一個TreeSet集合,使用Comparator接口的匿名內部類的匿名對象作爲比較器
        TreeSet<Animal> treeSet = new TreeSet<>(new Comparator() {
          	@Override
            public int compare(Animal o1, Animal o2) {
                if(o1.age!=o2.age) {
                    return o2.age - o1.age;
                }else {
                    return o1.name.compareTo(o2.name);
                }
            }
        });
      	//添加元素
      	treeSet.add(new Animal("大黃", 1));
      	treeSet.add(new Animal("旺財", 2));
      	//遍歷集合
      	Iterator<Animal> it = treeSet.iterator();
        while(it.hasNext()){
          	System.out.println(it.next());
        }
    }
}
//利用匿名內部類的簡寫
public static void main(String[] args) {
		// TODO Auto-generated method stub
		TreeSet<Animal> ts=new TreeSet<Animal>((o1, o2)->{
				// TODO Auto-generated method stub
				if(o1.getAge()!=o2.getAge()) {
					return o2.getAge()-o1.getAge();
				}else {
					return o1.getName().compareTo(o2.getName());
				}
			});
		//添加元素
		ts.add(new Animal("大黃",1));
		ts.add(new Animal("旺財",2));
		for(Animal a:ts) {
			System.out.println(a);
		}
}

SortedSet接口

TreeSet除了實現了Set接口外,還實現了SortedSet接口

SortedSet接口中常用的方法:
first()

返回此 set 中當前第一個(最低)元素。

last()

返回此 set 中當前最後一個(最高)元素。

headSet(E toElement)

返回此 set 的部分視圖,其元素嚴格小於toElement。

tailSet(E fromElement)

返回此 set 的部分視圖,其元素大於等於fromElement。

subSet(E fromElement, E toElement)

返回此 set 的部分視圖,其元素從 fromElement(包括)到 toElement(不包括)。

Last Demo

package com.qf.day16_2;

import java.util.Comparator;
import java.util.TreeSet;
/**
 * 上機練習:按照字母的長度來排列字符串  ,如果長度一樣 按照編碼順序排列
 *"dog"   "hello"  "beijing"   "tianjin"   "shanghai"   "guangzhou"
 */
public class Demo1 {
	public static void main(String[] args) {
		TreeSet<String> treeSet=new TreeSet<String>(new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				
				int n=o1.length()-o2.length();//升序
				int m=o1.compareTo(o2);//升序
				
				return n!=0?n:m;
			}
		});
		
		treeSet.add("beijing");
		treeSet.add("guangzhou");
		treeSet.add("shanghai");
		treeSet.add("tianjin");
		treeSet.add("hello");
		treeSet.add("dog");
		treeSet.add("no");
		
		System.out.println(treeSet);
	}
}

下一篇講解map接口。1


  1. 文章太長了 https://blog.csdn.net/l1996729/article/details/106639660 ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章