貝葉斯分類器及Python實現
集合
什麼是集合?
- 概念:物件的容器,定義了對多個物件進行操作的常用方法。可實現陣列的功能。
- 和陣列區別:
- (1)陣列長度固定,集合長度不固定
- (2)陣列可以儲存基本型別和引用型別,集合只能儲存引用型別
- 位置:java.util.*;
Collection體系集合
- Interface Collection:該體系結構的根介面,代表一組物件,稱為“集合”。
- List介面的特點:有序、有下標、元素可重複
- Set介面的特點:無序、無下標、元素不能重複
Collection父介面
-
特點:代表一組任意型別的物件,無序、無下標、不能重複。
-
方法:
- boolean add(Object obj) //新增一個物件
- boolean addAll(Collection c) //將一個集合中的所有物件新增到此集合中
- void clear() //清空此集合中的所有物件
- boolean contains(Object o) //檢查此集合中是否包含o物件
- boolean equals(Object o) //比較此集合是否與指定物件相等
- boolean isEmpty() //判斷此集合是否為空
- boolean remove(Object o) //在此集合中移除o物件
- int size() //返回此集合中的元素個數
- Object[] toArray() //將此集合轉換成陣列
package com.aggregation.demo01; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /** * Collection介面的使用 * (1)新增元素 * (2)刪除元素 * (3)遍歷元素 * (4)判斷 * @author 大白很白 */ public class demo01 { public static void main(String[] args) { //建立集合 Collection collection=new ArrayList(); //(1)新增元素 collection.add("蘋果"); collection.add("西瓜"); collection.add("榴蓮"); System.out.println("元素個數:"+collection.size()); System.out.println(collection); //(2)刪除元素 //collection.remove("榴蓮"); //collection.clear(); //System.out.println("刪除之後:"+collection.size()); //(3)遍歷元素【重點】 //3.1 使用增強for System.out.println("------------------3.1 使用增強for-----------------------"); for (Object object : collection){ System.out.println((String) object); } //3.2 使用迭代器(迭代器專門用來遍歷集合的一種方式) //hasNext();有沒有下一個元素 //next();獲取下一個元素 //remove();刪除當前元素 System.out.println("------------------3.2 使用增強for-----------------------"); Iterator it = collection.iterator(); while(it.hasNext()){ String s = (String) it.next(); System.out.println(s); // collection.remove(s);//不能在迭代器內使用collection.remove()方法,不可併發修改 //it.remove(); } System.out.println("元素個數:"+collection.size());//元素個數:0 //(4)判斷 System.out.println(collection.contains("西瓜")); System.out.println(collection.isEmpty()); } }
-
Collection的使用:儲存學生資訊
Student.java
package com.aggregation.demo01; /** * 學生類 * @ author 大白很白 */ public class Student { private String name; private int age; public Student(){ } public Student(String name, int age) { 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; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
Demo02.java
package com.aggregation.demo01; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /** * Collection的使用:儲存學生資訊 * @ author 大白很白 */ public class Demo02 { public static void main(String[] args) { //新建Collection物件 Collection collection = new ArrayList(); Student s1 = new Student("張三",16); Student s2 = new Student("李四",20); Student s3 = new Student("小王",18); //1新增資料 collection.add(s1); collection.add(s2); collection.add(s3); System.out.println("元素個數:"+collection.size()); System.out.println(collection.toString()); //2刪除 collection.remove(s1); //collection.clear();//清除集合中的元素,集合中儲存的實際是物件的地址,物件和集合之間指標指向 //System.out.println("刪除之後:"+collection.size()); //3遍歷 //3.1 增強for System.out.println("------------------3.1 增強for-------------------------"); for ( Object object:collection) { Student s = (Student)object; System.out.println(s.toString()); } //3.2 迭代器:hasNext(); next(); remove();迭代過程中不能使用collection的刪除方法 Iterator it = collection.iterator(); while(it.hasNext()){ Student s=(Student)it.next(); System.out.println(s.toString()); } //4 判斷 System.out.println(collection.contains(s1)); System.out.println(collection.isEmpty()); } }
-
迭代器
List子介面
-
特點:有序、有下標、元素可以重複。
-
方法:
-
void add(int index, Object o) //在index位置插入物件o
-
boolean addAll(int index, Collection c) //將一個集合中的元素新增到此集合中的index位置
-
Object get(int index) //返回集合中指定位置的元素
-
List subList(int fromIndex, int toIndex) //返回fromIndex和toIndex之間的集合元素
package com.aggregation.demo01; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** * List子介面的使用 * 特點:1 有序 有下表 2 可以重複 * @ author 大白很白 */ public class Demo03 { public static void main(String[] args) { //先建立集合物件 List list = new ArrayList<>(); //1新增元素 list.add("蘋果"); list.add("小米"); list.add(0,"華為"); System.out.println("元素個數:"+list.size());//元素個數:3 System.out.println(list.toString());//[華為, 蘋果, 小米] //2刪除元素 //list.remove(0); System.out.println("刪除之後:"+list.size());//刪除之後:3 System.out.println(list.toString());//[華為, 蘋果, 小米] //3遍歷 //3.1使用for遍歷 System.out.println("---------------------3.1使用for遍歷-----------------------"); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); /* 華為 蘋果 小米 */ } //3.2使用增強for System.out.println("---------------------3.2使用for遍歷-----------------------"); for (Object object:list) { System.out.println(object); /* 華為 蘋果 小米 */ } //3.3使用迭代器 System.out.println("---------------------3.3使用迭代器-----------------------"); Iterator it = list.iterator(); while(it.hasNext()){ System.out.println(it.next()); /* 華為 蘋果 小米 */ } //3.4使用列表迭代器,和Iterator的區別,ListIterator可以向前或者向後遍歷,新增、刪除、修改元素 ListIterator lit = list.listIterator(); System.out.println("---------------------3.4使用列表迭代器從前往後-----------------------"); while(lit.hasNext()){ System.out.println(lit.nextIndex()+":"+lit.next()); /* 0:華為 1:蘋果 2:小米 */ } System.out.println("---------------------3.4使用列表迭代器從後往前-----------------------"); while(lit.hasPrevious()){ System.out.println(lit.previousIndex()+":"+lit.previous()); /* 2:小米 1:蘋果 0:華為 */ } //4判斷 System.out.println(list.contains("蘋果"));//true System.out.println(list.isEmpty());//false //5獲取位置 System.out.println(list.indexOf("華為"));//0 } }
-
list新增數字資料
package com.aggregation.demo01; import java.util.ArrayList; import java.util.List; public class Demo04 { public static void main(String[] args) { //建立集合 List list = new ArrayList<>(); //1新增數字資料(自動裝箱) list.add(20); list.add(30); list.add(40); list.add(50); list.add(60); System.out.println("元素個數:"+list.size());//元素個數:5 System.out.println(list.toString());//[20, 30, 40, 50, 60] //2刪除操作 //list.remove(0); //list.remove(new Integer(20));//(Object)20 System.out.println("刪除元素:"+list.size());//刪除元素:5 System.out.println(list.toString());//[20, 30, 40, 50, 60] //3補充方法subList:返回子集合,含頭不含尾 List subList = list.subList(1, 3); System.out.println(subList.toString());//[30, 40] } }
-
List實現類
- ArrayList【重點】:
- 陣列結構實現,查詢快、增刪慢;
- JDK1.2版本,執行效率快、執行緒不安全。
- Vector:
- 陣列結構實現,查詢快、增刪慢;
- JDK1.0版本,執行效率慢、執行緒安全。
- LinkedList:
- 連結串列結構實現,增刪快,查詢慢。
- 連結串列:!
ArrayList的使用
-
Student.java 重寫了equals方法
package com.aggregation.demo01; /** * 學生類 * @ author 大白很白 */ public class Student { private String name; private int age; public Student(){ } public Student(String name, int age) { 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; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object obj) { //1判斷是否為同一個物件 if (this==obj) { return true; } //2判斷是否為空 if (obj==null){ return false; } //3判斷是否是Student型別 if (obj instanceof Student){ Student s = (Student)obj; //比較屬性 if (this.name.equals(s.getName())&&this.age==s.getAge()){ return true; } } //5不滿足條件返回false return false; } }
-
ArrayList的使用
package com.aggregation.demo01; import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator; /** * ArrayList的使用 * 儲存結構:陣列,查詢遍歷速度快,增刪慢 */ public class Demo05 { public static void main(String[] args){ //1新增元素 ArrayList<Object> arrayList = new ArrayList<>(); Student s1 = new Student("王德發",20); Student s2 = new Student("光頭強",22); Student s3 = new Student("趙四",18); arrayList.add(s1); arrayList.add(s2); arrayList.add(s3); System.out.println("元素個數:"+arrayList.size());//元素個數:3 System.out.println(arrayList.toString());//[Student{name='王德發', age=20}, Student{name='光頭強', age=22}, // Student{name='趙四', age=18}] //2刪除元素 //arrayList.remove(s1); //arrayList.remove(new Student("王德發",20));//重寫了equals方法 //System.out.println("刪除之後:"+arrayList.size());//刪除之後:2 //3遍歷元素【重點】 //3.1使用迭代器 System.out.println("-------------3.1使用迭代器------------------"); Iterator<Object> it = arrayList.iterator(); while(it.hasNext()){ Student s = (Student) it.next(); System.out.println(s.toString()); /* Student{name='王德發', age=20} Student{name='光頭強', age=22} Student{name='趙四', age=18} */ } //3.2列表迭代器 System.out.println("-------------3.2使用列表迭代器------------------"); ListIterator<Object> lit = arrayList.listIterator(); while(lit.hasNext()){ Student s = (Student) lit.next(); System.out.println(s.toString()); /* Student{name='王德發', age=20} Student{name='光頭強', age=22} Student{name='趙四', age=18} */ } System.out.println("-------------3.2使用列表迭代器逆序------------------"); while(lit.hasPrevious()){ Student s = (Student) lit.previous(); System.out.println(s.toString()); /* Student{name='趙四', age=18} Student{name='光頭強', age=22} Student{name='王德發', age=20} */ } //4判斷 // System.out.println(arrayList.contains(s1)); System.out.println(arrayList.contains(new Student("光頭強",22)));//true,重寫了equals方法 System.out.println(arrayList.isEmpty());//false //5查詢 //System.out.println(arrayList.indexOf(s1)); System.out.println(arrayList.indexOf(new Student("趙四",18)));//2 } }
ArrayList原始碼分析
原始碼分析:DEFAULT_CAPACITY = 10; 預設容量
注意:如果沒有向集合中新增任何元素時,容量為0;新增一個元素後,容量為10
每次擴容的大小為原來的1.5倍
EMPTY_ELEMENTDATA = {}; 存放元素的陣列
size 實際元素個數(<=容量)
add() 新增元素
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
Vector集合的使用
package com.aggregation.demo02;
import java.util.Enumeration;
import java.util.Vector;
/**
* 演示Vector集合的使用
* 儲存結構:陣列
* @author 大白很白
*/
public class Demo01 {
public static void main(String[] args) {
//1建立集合
Vector vector = new Vector();
//新增元素
vector.add("草莓");
vector.add("芒果");
vector.add("西瓜");
System.out.println("元素個數:"+vector.size());
//2刪除
//vector.remove(0);
//vector.remove("西瓜");
//vector.clear();
//3遍歷
//使用列舉器
Enumeration en = vector.elements();
while (en.hasMoreElements()){
String o = (String) en.nextElement();
System.out.println(o);
}
//4判斷
System.out.println(vector.contains("西瓜"));
System.out.println(vector.isEmpty());
//5 vector其他方法
//firstElement、lastElement、elementAt();
}
}
LinkedList的使用
package com.aggregation.demo02;
import com.aggregation.demo01.Student;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
/**
* LinkedList的使用
* 儲存結構:雙向連結串列
* @author 大白很白
*/
public class Demo02 {
public static void main(String[] args) {
//建立集合
LinkedList<Object> linkedList = new LinkedList<>();
//1新增元素
Student s1 = new Student("王德發",20);
Student s2 = new Student("光頭強",22);
Student s3 = new Student("趙四",18);
linkedList.add(s1);
linkedList.add(s2);
linkedList.add(s3);
linkedList.add(s3);
System.out.println("元素個數:"+linkedList.size());
System.out.println(linkedList.toString());
//2刪除
//linkedList.remove(s1);
//System.out.println("刪除之後:"+linkedList.size());
//linkedList.clear();
//3遍歷
//3.1for遍歷
System.out.println("--------------for------------");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.get(i));
}
//3.2增強for
System.out.println("--------------增強for-------------");
for (Object object:linkedList) {
Student s = (Student) object;
System.out.println(s.toString());
}
//3.3使用迭代器
System.out.println("--------------使用迭代器-------------");
Iterator<Object> it = linkedList.iterator();
while (it.hasNext()){
Student s = (Student) it.next();
System.out.println(s.toString());
}
//3.4使用列表迭代器
System.out.println("--------------使用列表迭代器-------------");
ListIterator<Object> listIterator = linkedList.listIterator();
while (listIterator.hasNext()){
Student s = (Student) listIterator.next();
System.out.println(s.toString());
}
//4判斷
System.out.println(linkedList.contains(s1));
System.out.println(linkedList.isEmpty());
//5獲取
System.out.println(linkedList.indexOf(s1));//下標0
}
}
LinkedList原始碼分析
Node first;連結串列的頭節點
Node last;連結串列的尾節點
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
ArrayList和LinkedList區別
LinkedList 雙向連結串列 或從尾到頭
ArrayList:必須開闢連續空間,查詢快,增刪慢。
LinkedList:無需開闢連續空間,查詢慢,增刪快。
泛型
- Java泛型是JDK1.5中引入的一個新特性,其本質是引數化型別,把型別作為引數傳遞。
- 常見形式有泛型類、泛型介面、泛型方法。
- 語法:
- <T,...>T稱為型別佔位符,表示一種引用型別。
- 好處:
- (1)提高程式碼的重用性
- (2)防止型別轉換異常,提高程式碼的安全性
泛型類
MyGeneric.java
package com.aggregation.demo02;
/**
* 泛型類
* 語法:類名<T>
* T是型別佔位符,表示一種引用型別,如果編寫多個,使用逗號隔開
* @author 大白很白
*/
public class MyGeneric<T> {
//使用泛型T
//1建立變數
T t;
//2泛型作為方法的引數
public void show(T t){
System.out.println(t);
}
//3使用泛型作為方法的返回值
public T getT(){
return t;
}
}
TestGeneric.java
package com.aggregation.demo02;
public class TestGeneric {
public static void main(String[] args) {
//使用泛型類建立物件
//注意:1泛型只能使用引用型別,2不同泛型物件之間不能相互複製
MyGeneric<String> myGeneric = new MyGeneric<String>();//後面的String可寫可不寫,JDK1.7之前必須寫
myGeneric.t="hello";
myGeneric.show("大家好,加油");
String string = myGeneric.getT();
MyGeneric<Integer> myGeneric2 = new MyGeneric<>();
myGeneric2.t=100;
myGeneric2.show(200);
Integer integer = myGeneric2.getT();
}
}
泛型介面
MyInterface.java
package com.aggregation.demo02;
/**
* 泛型介面
* 語法:介面名<T>
* 注意:不能建立泛型靜態常量
* @author 大白很白
* @param <T>
*/
public interface MyInterface<T> {
String name="羅小通";
T server(T t);
}
MyInterfaceImpl.java
package com.aggregation.demo02;
public class MyInterfaceImpl implements MyInterface<String>{//泛型需設定一個型別
@Override
public String server(String t) {
System.out.println(t);
return t;
}
}
MyInterfaceImpl2.java
package com.aggregation.demo02;
public class MyInterfaceImpl2<T> implements MyInterface<T> {//暫未指定型別,可使用時再指定
@Override
public T server(T t) {
System.out.println(t);
return t;
}
}
TestMyInterface.java
package com.aggregation.demo02;
public class TestMyInterface {
public static void main(String[] args) {
MyInterfaceImpl impl1 = new MyInterfaceImpl();
impl1.server("你充q幣嗎");
MyInterfaceImpl2<Integer> impl2 = new MyInterfaceImpl2<>();
impl2.server(1000);
}
}
泛型方法
MyGenericMethod.java
package com.aggregation.demo02;
/**
* 泛型方法
* 語法:<T>返回值型別
* @author 大白很白
*/
public class MyGenericMethod {
//泛型方法
public <T> T show(T t){
System.out.println("泛型方法:"+t);
return t;
}
}
TestMyGenericMethod
package com.aggregation.demo02;
public class TestMyGenericMethod {
public static void main(String[] args) {
MyGenericMethod myGenericMethod = new MyGenericMethod();
myGenericMethod.show("加油加油!");//泛型方法:加油加油!
myGenericMethod.show(200);//泛型方法:200
myGenericMethod.show(3.14);//泛型方法:3.14
}
}
泛型集合
-
概念:引數化型別、型別安全的集合,強制集合元素的型別必須一致。
-
特點:
- 編譯時即可檢查,而非執行時丟擲異常。
- 訪問時,不必型別轉換(拆箱)。
- 不同泛型之間引用不能相互賦值,泛型不存在多型。
package com.aggregation.demo02; import com.aggregation.demo01.Student; import java.util.ArrayList; import java.util.Iterator; public class Demo03 { public static void main(String[] args) { ArrayList<Student> arrayList = new ArrayList<Student>(); Student s1 = new Student("王德發",20); Student s2 = new Student("光頭強",22); Student s3 = new Student("趙四",18); arrayList.add(s1); arrayList.add(s2); arrayList.add(s3); Iterator<Student> it = arrayList.iterator(); while (it.hasNext()){ Student s = it.next(); System.out.println(s.toString()); } } }
Set子介面
- 特點:無序、無下標、元素不可重複。
- 方法:全部繼承自Collection中的方法。
Set實現類
- HashSet【重點】:
- 基於HashCode實現元素不重複。
- 當存入元素的雜湊碼相同時,會呼叫equals進行確認,如結果為true,則拒絕後者存入。
- TreeSet:
- 基於排列順序實現元素不重複。
- 實現了SortedSet介面,對集合元素自動排序。
- 元素物件的型別必須實現Comparable介面,指定排序規則。
- 通過ComparaTo方法確定是否為重複元素。
Set介面的使用
package com.aggregation.demo03;
import java.util.HashSet;
import java.util.Iterator;
/**
* 測試Set介面的使用
* 特點:(1)無序、沒有下標 (2)不能重複
* @大白很白
*/
public class Demo01 {
public static void main(String[] args) {
//建立集合
HashSet<String> set = new HashSet<>();
//1新增資料
set.add("蘋果");
set.add("華為");
set.add("小米");
System.out.println("資料個數:"+set.size());
System.out.println(set.toString());
//2刪除資料
//set.remove("蘋果");
//System.out.println(set.toString());
//3遍歷【重點】
//3.1增強for
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("華為"));
System.out.println(set.isEmpty());
}
}
HashSet的使用
Demo02
package com.aggregation.demo03;
import java.util.HashSet;
import java.util.Iterator;
/**
* HashSet集合的使用
* 儲存結構:雜湊表(陣列+連結串列+紅黑樹)
* @ author 大白很白
*/
public class Demo02 {
public static void main(String[] args) {
//新建集合
HashSet<String> hashSet = new HashSet<>();
//1新增元素
hashSet.add("羅通");
hashSet.add("羅小通");
hashSet.add("楊玉珍");
hashSet.add("老蘭");
System.out.println("元素個數:"+hashSet.size());
System.out.println(hashSet.toString());
//2刪除資料
//hashSet.remove("老蘭");
//System.out.println("刪除以後:"+hashSet.size());
//3遍歷操作
//3.1增強for
System.out.println("------------3.1增強for----------");
for (String string:hashSet) {
System.out.println(string);
}
//3.2使用迭代器
System.out.println("-------------3.2使用迭代器---------------");
Iterator<String> it = hashSet.iterator();
while (it.hasNext()){
//String s = it.next();
//System.out.println(s);
System.out.println(it.next());
}
//4判斷
System.out.println(hashSet.contains("老蘭"));
System.out.println(hashSet.isEmpty());
}
}
Demo03.java
package com.aggregation.demo03;
import java.util.HashSet;
/**
* HashSet的使用
* 儲存結構:雜湊表(陣列+連結串列+紅黑樹)
* @author 大白很白
*/
public class Demo03 {
public static void main(String[] args) {
//建立集合
HashSet<Person> persons = new HashSet<>();
//1新增資料
Person p1 = new Person("小紅",18);
Person p2 = new Person("小綠",19);
Person p3 = new Person("小黑",20);
persons.add(p1);
persons.add(p2);
persons.add(p3);
System.out.println("元素個數:"+persons.size());
System.out.println(persons.toString());
}
}
Person.java
package com.aggregation.demo03;
/**
* 人類
* @author 大白很白
*/
public class Person {
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 Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
HashSet儲存方式
儲存過程
- 根據hashcode計算儲存的位置,如果此位置為空,則直接儲存,如果不為空執行第二步
- 再執行equals方法,如果equals方法為true,則認為是重複,否則,形成連結串列
手動重寫hashcode和equals
package com.aggregation.demo03;
/**
* 人類
* @author 大白很白
*/
public class Person {
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 Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int hashCode() {
int n1=this.name.hashCode();
int n2=this.age;
return n1+n2;
}
@Override
public boolean equals(Object obj) {
if (this==obj){
return true;
}
if (obj==null){
return false;
}
if (obj instanceof Person){
Person p = (Person)obj;
if (this.name.equals(p.getName())&&this.age==p.getAge()){
return true;
}
}
return false;
}
}
使用快捷鍵重寫hashcode和equals:Alt+Insert
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
return getAge() == person.getAge() && Objects.equals(getName(), person.getName());
}
@Override
public int hashCode() {
return Objects.hash(getName(), getAge());
}
理解儲存過程(重複判斷依據)
package com.aggregation.demo03;
import java.util.HashSet;
import java.util.Iterator;
/**
* HashSet的使用
* 儲存結構:雜湊表(陣列+連結串列+紅黑樹)
* 儲存過程
* 1. 根據hashcode計算儲存的位置,如果此位置為空,則直接儲存,如果不為空執行第二步
* 2. 再執行equals方法,如果equals方法為true,則認為是重複,否則,形成連結串列
* @author 大白很白
*/
public class Demo03 {
public static void main(String[] args) {
//建立集合
HashSet<Person> persons = new HashSet<>();
//1新增資料
Person p1 = new Person("小紅",18);
Person p2 = new Person("小綠",19);
Person p3 = new Person("小黑",20);
persons.add(p1);
persons.add(p2);
persons.add(p3);
persons.add(new Person("小紅",18));//重寫了hashcode,equals
System.out.println("元素個數:"+persons.size());
System.out.println(persons.toString());
//2刪除操作
//persons.remove(p1);
//persons.remove(new Person("小紅",18));
//System.out.println("刪除之後:"+persons.size());
//3遍歷【重點】
//3.1使用增強for
for (Person person:persons) {
System.out.println(person.toString());
}
//3.2使用迭代器
System.out.println("--------------------------");
Iterator<Person> it = persons.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
//4判斷
System.out.println(persons.contains(new Person("小黑",20)));
System.out.println(persons.isEmpty());
}
}
TreeSet的使用
儲存String型別
Demo04.java
package com.aggregation.demo03;
import java.util.Iterator;
import java.util.TreeSet;
/**
* TreeSet的使用
* 儲存結構:紅黑樹
* @author 大白很白
*/
public class Demo04 {
public static void main(String[] args) {
//建立集合
TreeSet<String> treeSet = new TreeSet<>();
//1新增元素
treeSet.add("xyz");
treeSet.add("abc");
treeSet.add("hello");
treeSet.add("xyz");//元素不重複,未新增
System.out.println("元素個數:"+treeSet.size());
System.out.println(treeSet.toString());
//2刪除
//treeSet.remove("xyz");
//System.out.println("刪除之後:"+treeSet.toString());
//3遍歷
//3.1增強for
System.out.println("------------------------");
for (String string:treeSet) {
System.out.println(string);
}
//3,2使用迭代器
System.out.println("-----------------------");
Iterator<String> it = treeSet.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
//4判斷
System.out.println(treeSet.contains("abc"));
System.out.println(treeSet.isEmpty());
}
}
儲存Person型別
需實現Comparable介面
Person.java
package com.aggregation.demo03;
import java.util.Objects;
/**
* 人類
* @author 大白很白
*/
public class Person implements Comparable<Person>{
@Override
public int compareTo(Person o) {
int n1=this.getName().compareTo(o.getName());
int n2=this.age-o.getAge();
return n1==0?n2:n1;//如果n1=0,返回n2,否則返回n1
}
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 Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
// @Override
// public int hashCode() {
// int n1=this.name.hashCode();
// int n2=this.age;
//
// return n1+n2;
// }
//
// @Override
// public boolean equals(Object obj) {
// if (this==obj){
// return true;
// }
// if (obj==null){
// return false;
// }
// if (obj instanceof Person){
// Person p = (Person)obj;
//
// if (this.name.equals(p.getName())&&this.age==p.getAge()){
// return true;
// }
// }
// return false;
// }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
return getAge() == person.getAge() && Objects.equals(getName(), person.getName());
}
@Override
public int hashCode() {
return Objects.hash(getName(), getAge());
}
}
Demo05.java
package com.aggregation.demo03;
import java.util.Iterator;
import java.util.TreeSet;
/**
* 使用TreeSet儲存資料
* 儲存結構:紅黑樹
* 要求:元素必須要實現Comparable介面,compareTo()方法返回值為0,認為是重複元素
* @author 大白很白
*/
public class Demo05 {
public static void main(String[] args) {
//建立集合
TreeSet<Person> persons = new TreeSet<>();
//1新增元素
Person p1 = new Person("xyz",18);
Person p2 = new Person("hello",19);
Person p3 = new Person("zz",20);
Person p4 = new Person("zz",21);
persons.add(p1);
persons.add(p2);
persons.add(p3);
persons.add(p4);
System.out.println("元素個數:"+persons.size());
System.out.println(persons.toString());
//元素個數:4
//[Person{name='hello', age=19}, Person{name='xyz', age=18}, Person{name='zz', age=20}, Person{name='zz', age=21}]
//2刪除
//persons.remove(p1);
//persons.remove(new Person("xyz",18));
//System.out.println("刪除之後:"+persons.size());
//3遍歷
//3.1使用增強for
for (Person person:persons) {
System.out.println(person);
}
//3.2使用迭代器
System.out.println("------------------------");
Iterator<Person> it = persons.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
//4判斷
System.out.println(persons.contains(p1));
System.out.println(persons.isEmpty());
}
}
Comparator介面
Comparator:實現定製比較(比較器)
Demo06.java
package com.aggregation.demo03;
import java.util.Comparator;
import java.util.TreeSet;
/**
* TreeSet集合的使用
* Comparator:實現定製比較(比較器)
* Comparable:可比較的
* @author 大白很白
*/
public class Demo06 {
public static void main(String[] args) {
//建立集合,並指定比較規則
TreeSet<Person> persons = new TreeSet<>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int n1=o1.getAge()-o2.getAge();
int n2=o1.getName().compareTo(o2.getName());
return n1==0?n2:n1;
}
});
Person p1 = new Person("xyz",18);
Person p2 = new Person("hello",19);
Person p3 = new Person("zz",20);
Person p4 = new Person("dd",20);
persons.add(p1);
persons.add(p2);
persons.add(p3);
persons.add(p4);
System.out.println(persons.toString());
}
}
TreeSet案例
要求:使用TreeSet集合實現字串按照長度進行排序
Demo07.java
package com.aggregation.demo03;
import java.util.Comparator;
import java.util.TreeSet;
/**
* 要求:使用TreeSet集合實現字串按照長度進行排序
* helloworld zhang lisi wangwwu beijing xian nanjing
* Comparator介面實現定製比較
*/
public class Demo07 {
public static void main(String[] args) {
//建立集合,並指定比較規則
TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int n1=o1.length()-o2.length();
int n2=o1.compareTo(o2);
return n1==0?n2:n1;
}
});
//新增資料
treeSet.add("helloworld");
treeSet.add("cat");
treeSet.add("superman");
treeSet.add("puppy");
treeSet.add("lightning");
treeSet.add("ball");
System.out.println(treeSet.toString());
}
}
Map集合
map介面的特點:
- 用於儲存任意鍵值對(Key-Value)
- 鍵:無序、無下標、不允許重複(唯一)
- 值:無序、無下標、允許重複
Map父介面
- 特點:儲存一對資料(Key-Value),無序、無下標,鍵不可重複,值可重複
- 方法:
- V put(K key,V value) //將物件存入到集合中,關聯鍵值。key重複則覆蓋原值。
- Object get(Object key) //根據鍵獲取對應的值。
- Set
//返回所有Key。 - Collection
values() //返回包含所有值的Collection集合。 - Set<Map.Entry<K,V>> //鍵值匹配的Set集合。
Map介面的使用
Demo01.java
package com.aggregation.demo04;
import java.util.HashMap;
import java.util.Map;
/**
* Map介面的使用
* 特點:(1)儲存鍵值對(2)鍵不能重複,值可以重複(3)無序
* @author 大白很白
*/
public class Demo01 {
public static void main(String[] args) {
//建立Map集合
Map<String, String> map = new HashMap<>();
//1新增元素
map.put("cn","中國");
map.put("uk","英國");
map.put("usa","美國");
map.put("cn","zhongguo");//元素並未增加,但值會覆蓋
System.out.println("元素個數:"+map.size());
System.out.println(map.toString());
//2刪除
// map.remove("usa");
// System.out.println("刪除之後:"+map.size());
//3遍歷
//3.1使用keySet();
System.out.println("---------------keySet()-------------------");
//Set<String> keySet = map.keySet();
for (String key :map.keySet()) {
System.out.println(key+"----"+map.get(key));
/*---------------keySet()-------------------
usa----美國
uk----英國
cn----zhongguo*/
}
//3.2使用entrySet()方法
System.out.println("-----------entrySet()--------------");
//Set<Map.Entry<String, String>> entrySet = map.entrySet();
for (Map.Entry<String, String> entry:map.entrySet()) {
System.out.println(entry.getKey()+"--------"+entry.getValue());
/* -----------entrySet()--------------
usa--------美國
uk--------英國
cn--------zhongguo*/
}
//4判斷
System.out.println(map.containsKey("cn"));
System.out.println(map.containsValue("泰國"));
}
}
Map集合的實現類
- HashMap【重點】:
- JDK1.2版本,執行緒不安全,執行效率快;允許用null作為key或是value。
- Hashtable:
- JDK1.0版本,執行緒安全,執行效率慢;不允許null作為key或是value。
- Properties:
- Hashtable的子類,要求key和value都是String。通常用於配置檔案的讀取。
- TreeMap:
- 實現了SortedMap介面(是Map的子介面),可以對key自動排序。
HashMap的使用
Students.java
package com.aggregation.demo04;
import java.util.Objects;
public class Student {
private String name;
private int stuNo;
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getStuNo() {
return stuNo;
}
public void setStuNo(int stuNo) {
this.stuNo = stuNo;
}
public Student(String name, int stuNo) {
this.name = name;
this.stuNo = stuNo;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", stuNo=" + stuNo +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
return getStuNo() == student.getStuNo() && Objects.equals(getName(), student.getName());
}
@Override
public int hashCode() {
return Objects.hash(getName(), getStuNo());
}
}
Demo02.java
package com.aggregation.demo04;
import java.util.HashMap;
import java.util.Map;
/**
* HashMap集合的使用
* 儲存結構:雜湊表(陣列+連結串列+紅黑樹)
* 使用key得hashcode和equals作為重複依據
* author 大白很白
*/
public class Demo02 {
public static void main(String[] args){
//剛建立hashmap之後沒有新增元素table==null size=0 目的:節省空間
//建立集合
HashMap<Student, String> students = new HashMap<>();
//1新增元素
Student s1 = new Student("小紅",1);
Student s2 = new Student("小綠",2);
Student s3 = new Student("小黑",3);
students.put(s1,"地球");
students.put(s2,"火星");
students.put(s3,"水星");
//students.put(s3,"金星");
students.put(new Student("小紅",1),"黑洞");
System.out.println("元素個數:"+students.size());
System.out.println(students.toString());
//2刪除
// students.remove(s1);
// System.out.println("刪除之後:"+students.size());
// System.out.println(students.toString());
//3遍歷
//3.1使用keySet();
System.out.println("------------keySet()------------------");
for (Student key:students.keySet()) {
System.out.println(key.toString()+"---------"+students.get(key));
}
//3.2使用entrySet();
System.out.println("-------------entrySet()-------------");
for (Map.Entry<Student, String> entry : students.entrySet()){
System.out.println(entry.getKey()+"----------"+entry.getValue());
}
//4判斷
System.out.println(students.containsKey(s1));
System.out.println(students.containsValue("宇宙"));
}
}
HashMap原始碼分析
1 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; //hashMap初始容量大小
2 static final int MAXIMUM_CAPACITY = 1 << 30;//hashMap的陣列最大容量
3 static final float DEFAULT_LOAD_FACTOR = 0.75f;//預設載入因子
4 static final int TREEIFY_THRESHOLD = 8;//jdk1.8當連結串列長度大於8時,調整成紅黑樹
5 static final int UNTREEIFY_THRESHOLD = 6;//jdk1.8 當連結串列長度小於6時,調整成連結串列
6 static final int MIN_TREEIFY_CAPACITY = 64;//jdk1.8 當連結串列長度大於8時,並且集合元素個數大於等於64時,調整成紅黑樹
7 transient Node<K,V>[] table;//雜湊表中的陣列
8 size;//元素個數
無參構造
public HashMap(){
this.loadFactor = DEFAULT_LOAD_FACTOR;// all other fields defaulted
}
put方法
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
總結:
- HashMap剛建立時,table是null,為了節省空間,當新增第一個元素時,table容量調整為16
- 當元素個數大於閾值(16*0.75=12)時,會進行擴容,擴容後大小為原來的2倍。目的是減少調整元素的個數。
- jdk1.8 當每個連結串列長度大於8,並且陣列元素個數大於等於64時,會調整為紅黑樹,目的提高執行效率
- jdk1.8當連結串列長度小於6時,調整成連結串列
- jdk1.8以前,連結串列是頭插入,jdk1.8以後是尾插入
TreeMap的使用
需實現Comparable介面,或者使用定製比較comparator
Student.java
package com.aggregation.demo04;
import java.util.Objects;
public class Student implements Comparable<Student>{
@Override
public int compareTo(Student o) {
//int n1=this.name.compareTo(o.getName());
int n2=this.stuNo-o.getStuNo();
return n2;
}
private String name;
private int stuNo;
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getStuNo() {
return stuNo;
}
public void setStuNo(int stuNo) {
this.stuNo = stuNo;
}
public Student(String name, int stuNo) {
this.name = name;
this.stuNo = stuNo;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", stuNo=" + stuNo +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
return getStuNo() == student.getStuNo() && Objects.equals(getName(), student.getName());
}
@Override
public int hashCode() {
return Objects.hash(getName(), getStuNo());
}
}
Demo03.java
package com.aggregation.demo04;
import java.util.Map;
import java.util.TreeMap;
/**
* TreeMap的使用
* 儲存結構:紅黑樹
* author 大白很白
*/
public class Demo03 {
public static void main(String[] args) {
//新建集合 或用定製比較 comparator
TreeMap<Student, String> treeMap = new TreeMap<>();
//1新增元素
Student s1 = new Student("小紅",1);
Student s2 = new Student("小綠",2);
Student s3 = new Student("小黑",3);
treeMap.put(s1,"成都");
treeMap.put(s2,"廣州");
treeMap.put(s3,"上海");
treeMap.put(new Student("小黑",3),"北京");//值覆蓋
System.out.println("元素個數:"+treeMap.size());
System.out.println(treeMap.toString());
//2刪除
//treeMap.remove(s3);
//treeMap.remove(new Student("小紅",1));
//System.out.println("刪除之後:"+treeMap.size());
//3遍歷
//3.1使用keySet()
System.out.println("-----------使用keySet()---------");
for (Student key:treeMap.keySet()) {
System.out.println(key+"-----"+treeMap.get(key));
}
//3.2使用entrySet()
System.out.println("-------------使用entrySet()-----------");
for (Map.Entry<Student, String>entry:treeMap.entrySet()) {
System.out.println(entry.getKey()+"-----"+entry.getValue());
}
//判斷
System.out.println(treeMap.containsKey(new Student("小黑",3)));
}
}
Collections工具類
-
概念:集合工具類,定義了除了存取以外的集合常用方法。
-
方法:
-
public static void reverse(List<?> list) //反轉集合中元素的順序
-
public static void shuffle(List<?> list) //隨機重置集合元素的順序
-
public static void sort(List
list) //升序排序(元素型別必須實現Comparable介面)
-
Demo04.java
package com.aggregation.demo04;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* 演示Collections工具類的使用
* @author 大白很白
*/
public class Demo04 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(20);
list.add(15);
list.add(17);
list.add(2);
list.add(8);
list.add(10);
//sort排序
System.out.println("排序之前:"+list.toString());
Collections.sort(list);
System.out.println("排序之後:"+list.toString());
// 排序之前:[20, 15, 17, 2, 8, 10]
// 排序之後:[2, 8, 10, 15, 17, 20]
//binarySearch二分查詢
int i = Collections.binarySearch(list, 15);
System.out.println(i);//3,找到>=0;沒找到,負數
//copy複製
List<Integer> dest = new ArrayList<>();//長度不同,需注意
for (int j = 0; j < list.size(); j++) {
dest.add(0);
}
Collections.copy(dest,list);
System.out.println(dest.toString());//[2, 8, 10, 15, 17, 20]
//reverse反轉
Collections.reverse(list);
System.out.println("反轉之後:"+list);//反轉之後:[20, 17, 15, 10, 8, 2]
//shuffle 打亂
Collections.shuffle(list);
System.out.println("打亂之後:"+list);//打亂之後:[8, 2, 10, 17, 15, 20]
//補充: list轉成陣列
System.out.println("--------list轉成陣列-----------");
Integer[] arr = list.toArray(new Integer[7]);
System.out.println(arr.length);//7
System.out.println(Arrays.toString(arr));//[15, 20, 8, 2, 17, 10, null]
//陣列轉成集合
System.out.println("----------陣列轉成集合---------");
String[] names={"張三","李四","王武"};
//集合是一個受限集合,不能新增和刪除
List<String> list2 = Arrays.asList(names);
//list2.add("趙六");
//list2.remove(0);
System.out.println(list2);
//把基本型別陣列轉成集合時,需要修改為包裝類
Integer[] nums = {100,200,300,400,500};
List<Integer> list3 = Arrays.asList(nums);
System.out.println(list3);//[100, 200, 300, 400, 500]
}
}
集合總結
- 集合的概念:
- 物件的容器,和陣列類似,定義了多個物件進行操作的常用方法。
- List集合:
- 有序、有下標、元素可以重複。(ArrayList、LinkedList、Vector)
- Set集合
- 無序、無下標、元素不可重複。(HashSet、TreeSet)
- Map集合:
- 儲存一對資料,無序、無下標,鍵不可重複,值可重複。(HashMap、HashTable、TreeMap)
- Collections:
- 集合工具類,定義了除了存取以外的集合常用方法。