1. 程式人生 > >Java學習lesson 15

Java學習lesson 15

set集合

*Set集合

一個包含重復的元素collection,並且最多包含一個null元素,此類實現Set接口,有哈希表支持,Java中的預定義類型如String、Integer都可以在集合內使用;但對於自己創建的類型是,要註意到Set

需要一種方式來維護存儲順序,而存儲順序如何維護,則是在Set的不同實現間會有所變化。因此,不同的Set實現不僅具有不同的行為,而且他們對於可以在特定是我Set抓狂那個放置的元素類型也有不同要求

繼承自Collection集合,哈希表通過它的自實現類HashSet集合實例化,HashSet集合底層是HashMap的實現

*List集合與Set集合的區別

List集合:元素是不唯一的,有序性(存儲和取出是不一致的)

Set集合:元素是唯一的,存儲和取出是不一致的

自定義存儲對象沒有重寫 hashCode與equals方法,將無法保證元素的唯一性

package set;

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

public class SetDemo {

	public static void main(String[] args) {
	//創建Set集合對象,Set集合是通過HashSet實現的
         Set<String> set=new HashSet<String>();
         //向集合中添加元素
         set.add("hello");
         set.add("hello");
         set.add("JavaSE");
         set.add("world");
         set.add("world");
         set.add("Java");
         
         //增強for循環,遍歷元素
         for(String str : set){
        	 System.out.println(str);
         }
	}

}

技術分享


*HashSet集合的add()方法,底層依賴於雙列集合HashMap<K,V>的put(K key,V value)來實現的

put(K key,V value)底層是依賴於HashCod()和equals()

傳遞元素的時候,首先判斷的是每一個元素對應的HashCode值是否一樣,如果HashCode值一樣,還要比較他們的equals()方法。由於現在集合存儲的是String類型,String類型本身重寫了equals()方法,所以默認比較的是內容是否相同,這裏最終返回的就是第一次存儲的那個元素,由此保證集合內元素的唯一性

(為快速查找而設計的Set,存入HashSet的元素必須定義hashCode())

package set;

import java.io.Serializable;
import java.util.HashSet;

public class HashSetDemo1 implements Serializable{
	private static final long serialVersionUID = 1L;
	transient int num ;
	public static void main(String[] args) {
		//創建集合對象 
		HashSet<String> hs=new HashSet<String>();
		//向集合中添加元素
		hs.add("hello");
		hs.add("world");
		hs.add("hello");
		hs.add("JavaSe");
		hs.add("Java");
		hs.add("word");
		hs.add("JavaWab");
		//加強for循環,遍歷集合
		for(String str :hs){
			System.out.println(str);
		}
	}

}


技術分享

//需求:存儲自定義對象並遍歷(使用HashSet集合)

HashSet<Student>()

package set;
//自定義類
public class Student {
	private String name;
	private int age;
	public Student() {
		super();
	}
	
	public Student(String name, int age) {
		super();
		this.name = name;
		this.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;
	}
	
}


//測試類

package set;

import java.util.HashSet;

public class HashSetDemo {
	public static void main(String[] args){
		//創建HashSet集合對象
		HashSet<Student> hs=new HashSet<Student>();
		//創建學生對象
		Student st1=new Student("蘋果",3);
		Student st2=new Student("梨",24);
		Student st3=new Student("桔子",15);
		Student st4=new Student("桔子",15);
		Student st5=new Student("桔子",17);
		Student st6=new Student("核桃",21);
		//向集合中添加元素
		hs.add(st1);
		hs.add(st2);
		hs.add(st3);
		hs.add(st4);
		hs.add(st5);
		hs.add(st6);
		//增強for循環,遍歷集合
		for(Student st :hs){
			System.out.println(st.getName()+"-----"+st.getAge());
		}
			
	}

}


技術分享

*TreeSet(Set集合的重點)

(保持次序的Set,底層依賴於TreeMap實例,底層為紅黑樹結構,可以從Set中提取有序的序列)

*有兩個構造方法(取決於開發者使用的是什麽養的構造方法)

*public TreeSet():無參構造:根據其元素的自然順序進行排序

package treeset;

import java.util.TreeSet;

public class TreeSetDemo {

	public static void main(String[] args) {
		
		//調用無參構造;元素將以自然排序進行排序
		TreeSet<Integer> ts=new TreeSet<Integer>();
		//向集合中添加元素
		ts.add(67);
		ts.add(45);
		ts.add(64);
		ts.add(98);
		ts.add(23);
		//遍歷元素
		for(Integer in : ts){
			System.out.print(in+" ");
		}	
	}

}

技術分享


*publict TreeSet(Comparaptr<E> com)

*對於TreeSet集合要實現自然排序,那麽該集合中存儲的自定義類型必須實現Comparable接口, 並且必須重寫該接口中的CompareTo()方法

*重寫了Comparable接口中的CompareTo方法中代碼需要自己給出(排序模式)

package treeset;
//對於TreeSet集合存儲自定義對象必須實現一個接口:compareable接口
public class Student implements Comparable<Student> {
	private String name;
	private int age;
	
	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		this.name = name;
		this.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 int compareTo(Student st) {
		//排序的代碼了,需要定義排序的條件
		//主要條件:按照學生的年齡從小到大進行排序
		int num =st.age - this.age ;//年齡從大到小 
               //比較完主要條件,還要還要比較次要條件:姓名內容也需要相同
		int num2 = num==0 ? this.name.compareTo(st.name): num ;
		return num2 ;
	}
}  
package treeset;

import java.util.TreeSet;

public class TreeSetDemo1 {
	public static void main(String[] args){
		//創建對象
		TreeSet<Student> ts=new TreeSet<Student>();
		//創建Student對象
		Student st1=new Student("山鬼謠",24);
		Student st2=new Student("山鬼謠",25);
		Student st3=new Student("弋痕夕",24);
		Student st4=new Student("山鬼謠",24);
		Student st5=new Student("千鈞",15);
		Student st6=new Student("千鈞",17);
		Student st7=new Student("辰月",16);
		//向集合中添加元素
		ts.add(st1);
		ts.add(st2);
		ts.add(st3);
		ts.add(st4);
		ts.add(st5);
		ts.add(st6);
		ts.add(st7);
		//遍歷元素,按年齡降序排列
		for(Student st : ts){
			System.out.println(st.getName()+"----"+st.getAge());
		}
	}
}

技術分享

//鍵盤錄入5個學生信息(姓名,語文成績,數學成績,英語成績),按照總分從高到低輸出到控制臺

package treeset;

public class Student1 {
	private String name;
	private int chineseScore;
	private int englishScore;
	private int mathScore;
	public Student1() {
		super();
	}
	public Student1(String name, int chineseScore, int englishScore,
			int mathScore) {
		super();
		this.name = name;
		this.chineseScore = chineseScore;
		this.englishScore = englishScore;
		this.mathScore = mathScore;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getChineseScore() {
		return chineseScore;
	}
	public void setChineseScore(int chineseScore) {
		this.chineseScore = chineseScore;
	}
	public int getEnglishScore() {
		return englishScore;
	}
	public void setEnglishScore(int englishScore) {
		this.englishScore = englishScore;
	}
	public int getMathScore() {
		return mathScore;
	}
	public void setMathScore(int mathScore) {
		this.mathScore = mathScore;
	}
	
	public int getSum(){
		return this.chineseScore+this.englishScore+this.mathScore;
	}
}


package treeset;

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

public class TreeSetDemo2 {

	public static void main(String[] args) {
		// 創建TreeSet集合對象,使用有參構造
		// 比較器排序匿名內部類的方式
		TreeSet<Student1> ts = new TreeSet<Student1>(new Comparator<Student1>() {
			public int compare(Student1 st1, Student1 st2) {
		// 主要條件:總分從高到到第進行排序
				int num = st2.getSum() - st1.getSum();

				// 總分相同,不一定語文成績相同,比較語文成績
				int num2 = num == 0 ? st1.getChineseScore() - st2.getChineseScore() : num;

				// 總分相同,語文成績相同,比較數學成績
				int num3 = num2 == 0 ? st1.getEnglishScore() - st2.getEnglishScore() : num2;

				// 總分相同,語文成績相同,數學相同,比較英語
				int num4 = num3 == 0 ? st1.getMathScore() - st2.getMathScore() : num3;

				// 總分以及各科成績都相同,不一定是同一個人,姓名內容是否相同
				int num5 = num4 == 0 ? st1.getName().compareTo(st2.getName()): num4;
				return num5;
				}
				});

				System.out.println("錄入學生信息開始:");
				// 鍵盤錄入5個學生的信息,姓名,語文成績,數學成績,英語成績
				for (int i=1;i<=5;i++) {
					// 創建鍵盤錄入對象
					// 為了方便錄入數據,數據類型都使用String類型接收
					Scanner sc = new Scanner(System.in);
					System.out.println("請輸入第"+i+"個學生的姓名:");
					String name = sc.nextLine();
					System.out.println("請輸入第" +i+ "個學生的語文成績:");
					String chineseStr = sc.nextLine();
					System.out.println("請輸入第" +i+ "個學生的英語成績:");
					String mathStr = sc.nextLine();
					System.out.println("請輸入第" +i+ "個學生的數學成績:");
					String englishStr = sc.nextLine();

					// 創建一個學生對象,把這些信息封裝到學生對象中
					Student1 st = new Student1();
					st.setName(name);
					st.setChineseScore(Integer.parseInt(chineseStr));
					st.setEnglishScore(Integer.parseInt(mathStr));
					st.setMathScore(Integer.parseInt(englishStr));

					// 將學生對象添加到集合中
					ts.add(st);
				}

				System.out.println("學生信息錄入結束:");
				System.out.println("學生信息總分從高到底排列如下:");
				//\t是制表符
				System.out.println("姓名\t語文成績\t數學成績\t英語成績");

				// 增強for遍歷集合
				for (Student1 std : ts) {
					System.out.println(std.getName() + "\t" + std.getChineseScore() + "\t"
							+ std.getEnglishScore() + "\t" + std.getMathScore());
				}
	}

}

技術分享


*對自定義對象什麽情況下保證元素是唯一的

成員變量相同,認為是同一個元素

主要條件給定,需要分析次要條件

*使用比較器排序,使用匿名內部類

使用有參構造創建TreeSet集合對象

*LinkedHashSet<E>

具有可預知順序的Set接口的哈希表鏈表實現

*由哈希保證元素的唯一性,有鏈接列表保證元素的有序性

package linkedhashset;

import java.util.LinkedHashSet;

public class LinkedHashSetDemo {
	public static void main(String[] args) {
		//創建LinkedHashSet集合對象
		LinkedHashSet<String> link = new LinkedHashSet<String>();
				
		//給集合中添加元素
		link.add("hello") ;
		link.add("hello") ;
		link.add("world") ;
		link.add("Java") ;
		link.add("JavaSE") ;
		link.add("world") ;
				
		//增強 for循環,遍歷集合
		for(String s: link){
					System.out.println(s);
				}
	}

}

技術分享


Java學習lesson 15