HashSet的儲存和遍歷
1、特點
1、HashSet實現 Set 介面,由雜湊表(實際上是一個 HashMap 例項)支援。
2、它不保證 set 的迭代順序;特別是它不保證該順序恆久不變。此類允許使用 null 元素。
3、Set介面定一個不包含重複元素的 collection,HashSet的元素自然也不能重複
4、只能儲存引用型別,JDK1.5後對基本型別有了自動裝箱,會將基本型別自動轉換為其包裝類。
2、add方法分析
boolean add(E e);如果此 set 中尚未包含指定元素,則新增指定元素。
該方法底層分析:
1、首先獲取待新增元素的雜湊值(e.hashCode();),與集合中的元素的雜湊值進行比較。
2、如果集合中不存在與待新增元素雜湊值相同的元素
3、如果集合中存在與待新增元素雜湊值相同的元素,則呼叫equals()方法比較這兩個元素,如果不相同就新增,否則不新增
注意:如果沒有重寫equals方法,則呼叫的是Object中的equal()方法,比較這兩個元素的地址,如果地址不相同,就將待新增的元素,新增到集合中,否則不新增。
4、所以一般情況下,需要根據具體的要求重寫hashCode方法和equals方法。
3、新增String字串
Java程式碼
public static void main(String[] args) {
//建立集合物件
HashSet<String> hs=new HashSet<String>();
String str1="hello";
String str2="world";
String str3="java";
String str4="hello";
System.out.println("str1的雜湊值:"+str1.hashCode());
System.out.println("str2的雜湊值:"+str2.hashCode());
System.out.println("str3的雜湊值:"+str3.hashCode());
System.out .println("str4的雜湊值:"+str4.hashCode());
hs.add(str1);
hs.add(str2);
hs.add(str3);
hs.add(str4);
System.out.println("====================");
for (String string : hs) {
System.out.println(string);
}
}
執行結果:
str1的雜湊值:99162322
str2的雜湊值:113318802
str3的雜湊值:3254818
str4的雜湊值:99162322
====================
world
java
hello
分析:
1、可以看出最後一個hello元素沒有進入集合,且集合中的元素順序和存入的順序不同。
2、String類重寫的hashCode方法,所以獲取雜湊值,呼叫的是String類中的hashCode方法
3、上述程式碼中看到str1和str2、str3的雜湊值互不相同,和str4的雜湊值相同,
4、集合為空,str1直接新增進入集合,
5、str1、tr2、str3互不相同,所以str2、str3、也新增到集合中,
6、str4與str3的雜湊值相同,此時呼叫String類的equals方法,比較字串的值,發現相同,不新增str4
4、新增物件
需求:儲存自定義物件,並保證元素的唯一性
要求:如果兩個物件的成員變數值都相同,則視為同一個元素
學生物件:
package com.xiaowen.demo2;
public class Student {
private String name;
private String age;
public Student() {
}
public Student(String name, String age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
測試類:
public static void main(String[] args) {
//建立集合物件
HashSet<Student> hs=new HashSet<Student>();
//建立學生物件
Student s1=new Student("小A","10");
Student s2=new Student("小B","20");
Student s3=new Student("小C","30");
Student s4=new Student("小D","40");
Student s5=new Student("小D","40");
System.out.println("s4:"+s4.hashCode());
System.out.println("s5:"+s5.hashCode());
hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4);
hs.add(s5);
hs.add(s4);
System.out.println("=========================");
for (Student student : hs) {
System.out.println(student);
}
}
執行結果:
s4:865113938
s5:1442407170
=========================
Student [name=小D, age=40]
Student [name=小B, age=20]
Student [name=小A, age=10]
Student [name=小C, age=30]
Student [name=小D, age=40]
分析:此時會發現s4和s5的雜湊值不同,但是s4和s5的成員變數的值都相同,所以集合中出現了重複的元素(此處的重複指的是成員變數值都相同),此時呼叫的是Object中的hashCode和equals方法,所以就需要在Student類中重寫hashCode方法和equals方法。
重寫後的Student類:
package com.xiaowen.demo2;
public class Student {
private String name;
private String age;
public Student() {
}
public Student(String name, String age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@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 == null) ? 0 : age.hashCode());
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 == null) {
if (other.age != null)
return false;
} else if (!age.equals(other.age))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
執行結果:此時 s5沒有新增到集合中
s4:783066
s5:783066
=========================
Student [name=小D, age=40]
Student [name=小C, age=30]
Student [name=小B, age=20]
Student [name=小A, age=10]
分析:
1、重寫hashCode方法,根據成員變數的雜湊值和成員變數的值,按照一定的規則生成新的雜湊值
2、重寫equals方法,比較成員變數的值
補充:
LinkedHashSet:底層資料結構由雜湊表和連結串列組成,其特點是元素唯一且有序
相關推薦
HashSet的儲存和遍歷
1、特點 1、HashSet實現 Set 介面,由雜湊表(實際上是一個 HashMap 例項)支援。 2、它不保證 set 的迭代順序;特別是它不保證該順序恆久不變。此類允許使用 null 元素
集合巢狀儲存和遍歷元素的示例
1 /** 2 * @Auther: lzy 3 * @Date: 2018/12/12 16:07 4 * @Description: 集合巢狀儲存和遍歷元素的示例 5 */ 6 public class ListTest { 7 public static void m
集合中的集合_儲存和遍歷(增強型for迴圈和迭代器)
package GuanQia3_test2_集合中套集合_第一次沒想明白; /* * 一個學科中有若干班級,每一個班級又有若干學生。整個學科一個大集合, * 若干個班級分為每一個小集合(集合巢狀之HashSet巢狀HashSet)。要求如下 * 1、 學生類有兩個屬
Java中ArrayList集合巢狀儲存和遍歷
student類: package day16_Test; /* * 學生類: * 成員變數:姓名、年齡 * 成員方法 * 構造方法 * *
PAT 1138 Postorder Traversal(二叉樹的儲存和遍歷)
題意:給出二叉樹的前序和中序遍歷,給出其後序遍歷的第一個元素。 思路:根據前序和中序遍歷的結果得到二叉樹的具體構造,再進行後序遍歷。 程式碼: #include <cstdio> #in
圖的儲存和遍歷
圖的儲存 圖的儲存一般有兩種方式:鄰接矩陣和鄰接表 鄰接矩陣 設圖G(V,E)的頂點標號為0,1,……n-1,則令二維陣列G[n][n]的兩維分別表示圖的頂點標號。 即如果G[i][j]等於1,指頂點i和頂點j之間有邊,如果G[i][j]等於0,指頂
圖的儲存和遍歷C++實現
最近在做一些OJ題目時,感覺自己圖的應用還不夠熟練。所以又翻書看別人的部落格複習了一下,現把圖的常用內容總結如下: 圖的常用儲存方法有:鄰接矩陣和鄰接表 遍歷方法有:按深度遍歷(DFS),按廣度遍歷(BFS) 下面的程式碼都是C++寫的,用了一些STL庫的容器:
資料結構之 二叉樹的儲存和遍歷總結
知道前序(包括空結點 下面程式碼用’,’代替)建立一個二叉樹,前序 中序 後序 層序輸出 如何求葉子結點數, 如何求二叉樹深度。 #include<stdio.h> #include<stdlib.h> #include<st
資料結構作業14—圖的概念 儲存結構和遍歷
2-1若無向圖G =(V,E)中含7個頂點,要保證圖G在任何情況下都是連通的,則需要的邊數最少是: (3分) A.16 B.21 C.15 D.6 作者: DS課程組 單位: 浙江大學 2-2對於有向圖,其鄰接矩陣表示比鄰接表
資料結構作業14—圖的概念 儲存結構和遍歷(判斷題)
1-1用鄰接矩陣法儲存圖,佔用的儲存空間數只與圖中結點個數有關,而與邊數無關。 (1分) T F 作者: DS課程組 單位: 浙江大學 1-2用鄰接表法儲存圖,佔用的儲存空間數只與圖中結點個數有關,而與邊數無關。 (1分) T
二維陣列的動態儲存(遍歷方陣,求各元素的和)
#define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; int **InitialArray(int row,int column) //動態建立陣列並初始化 {int
二叉樹的儲存方式和遍歷方式
二叉樹: 二叉樹的每個節點至多有兩個子樹。如這個二叉樹,其中1,2有兩個子樹,3只有左子樹,5有右子樹,4,6,7沒有子樹。 二叉樹有兩種儲存方式: 第一種,陣列表示。用陣列儲存方式就是用一組連續的儲存單元儲存二叉樹的資料元素。
常用資料結構-二叉樹的鏈式儲存、建立和遍歷
1. 鏈式二叉樹簡介 二叉樹是資料結構——樹的一種,一般定義的樹是指有一個根節點,由此根節點向下分出數個分支結點,以此類推以至產生一堆結點。樹是一個具有代表性的非線性資料結構,所謂的非
樹的創建和遍歷
樹#include <stdio.h>#include <stdlib.h>struct node{ char data; struct node* left; struct node* right;};void preorder(struct node* root)
數據結構與算法第10周作業——二叉樹的創建和遍歷算法
技術分享 truct order traverse eof 結構 後序遍歷 lib void 一、二叉樹的創建算法(遞歸方式) 二、二叉樹的先序、中序和後序遍歷算法 #include<stdio.h>#include<stdlib.h>typedef
數據結構-第10周作業(二叉樹的創建和遍歷算法)
樹的創建 創建 -1 數據結構 二叉 分享 com jpg 遍歷算法 數據結構-第10周作業(二叉樹的創建和遍歷算法)
數據結構學習筆記(五) 樹的創建和遍歷
一個 後序遍歷 for -1 堆棧 nor ext cnblogs 復制 創建(先序創建和根據先序和中序進行創建)和遍歷(先序遍歷、中序遍歷、後序遍歷、非遞歸堆棧遍歷、層次遍歷): package tree; public class XianCreateTree
Jsoup解析和遍歷一個HTML文檔(二)
spl nodes gif .org code htm ips method spa 關於Eclipse編輯器匯總console中字體調整: 1,下載jsoup的jar包:http://jsoup.org/download 2, jsoup英文的開發手冊:http:
線索二叉樹的構建和遍歷------小甲魚數據結構和算法
-- tag typedef pre == 約定 cnblogs amp scan #include <stdio.h> #include <stdlib.h> typedef char ElemType; // 線索存儲標誌位 // Link
二叉樹建立和遍歷
mil inorder 推斷 microsoft con 是否 font pac node 二叉樹創建遍歷規則: 1.先序:根-左-右 2.中序:左-根-右 3.後序:左-右-根 二叉樹定義和輔助函數例如以下: struct node {