1. 程式人生 > 實用技巧 >對大學生數學建模比賽演算法的一些理解

對大學生數學建模比賽演算法的一些理解

集合

  1. 概念:物件的容器,定義了多個物件進行操作的常用方法。可實現陣列的功能

  2. 集合記憶體的是物件的地址

  3. 和陣列的區別:

    1. 陣列長度固定,集合長度不固定

    2. 陣列可以儲存基本型別和引用型別,陣列只能儲存引用型別

    3. 位置:java.until.*;

collection體系集合

Collection父介面

特點:代表一組任意型別的物件,無序,無下標,不能重複

方法

  1. boolean add(Object obj)//新增一個物件

  2. boolean addAll(Collection c)//將一個集合中的所有物件新增到此集合中

  3. void clear()//清空此集合中的所有物件

  4. boolean contains(Object o)//檢查此集合中是否包含o物件

  5. boolean equals(Object o)//比較此集合是否與指定物件相等

  6. boolean isEmpty()//判斷此集合是否為空

  7. boolean remove(Object o)//在此集合中移除o物件

  8. int size()//返回此集合中的元素個數

  9. Object[] toArray()//將此集合轉換成陣列

迭代器:一個介面有hasnext(),next(),remove()函式,用hasnext遍歷所有元素並取出

package com.yyl.www.chapter01;
/**
* Collection介面的使用
* 1.新增元素
* 2.刪除元素
* 3.遍歷元素
* 4.判斷
* @author yyl*/
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Demo01 {
public static void main(String[] args) {
Collection collection=new ArrayList();
//新增元素
collection.add("蘋果");
collection.add("西瓜");
collection.add("榴蓮");
System.out.println("元素個數"+ collection.size());
System.out.println(collection.toString());
//刪除元素
//collection.remove("榴蓮");
//collection.clear();//清空集合
//System.out.println("刪除之後"+ collection.size());

//遍歷集合[重點]

//使用增強for
for (Object object:collection) {
System.out.println(object);
}
//使用迭代器 (迭代器專門用來遍歷集合的一種方式)
//hasNext();有沒有下一個元素
//next();獲取下一個元素
//remove();刪除當前元素
Iterator it=collection.iterator();
while(it.hasNext()){
Object s=it.next();
System.out.println(s);
//collection.remove(s);//ConcurrentModificationException發生異常,迭代器使用過程中只能用迭代器方法
//ConcurrentModificationException 併發異常,不允許併發修改
it.remove();
}
System.out.println("元素個數"+collection.size());

//判斷
System.out.println(collection.contains("西瓜"));
System.out.println(collection.isEmpty());
}

  1. 集合新增物件實際上把物件的地址放入集合的空間中

package com.yyl.www.chapter01;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

//collection使用,儲存學生資訊
public class Demo02 {
public static void main(String[] args) {
//新建collection物件
Collection collection=new ArrayList();
//1.新增資料
Student s1=new Student("張三",20);
Student s2=new Student("李四",18);
Student s3=new Student("王五",22);
collection.add(s1);
collection.add(s2);
collection.add(s3);
collection.add(s3);
System.out.println("元素個數"+collection.size());
System.out.println(collection.toString());
//刪除
collection.remove(s3);
//collection.remove(new Student("王五",22));//無效語句
System.out.println("刪除之後"+collection.toString());
//collection.clear();//清楚物件
System.out.println("—————————————增強for—————————————");
for (Object object:collection) {
Student s=(Student)object;
System.out.println(s.toString());
}
System.out.println("———————————————迭代器—————————————");
Iterator iterator=collection.iterator();
while(iterator.hasNext()){
Student s=(Student)iterator.next();
System.out.println(s.toString());
}
//判斷
System.out.println(collection.contains(new Student("王五",22)));//輸出false,s3和這個新物件無關係
System.out.println(collection.isEmpty());
}
}

List介面

  1. 特點:有序,有下標,元素可以重複

  2. 方法

    1. void add(int index,Object o)//在index位置插入物件o

    2. boolean addAll(int index,Collection c)//將一個集合中的元素新增到此集合中的index位置

    3. Object get(int index)//返回集合中指定位置的元素

    4. List subList(int fromIndex,int toIndex)//返回fromIndex和toIndex之間的集合元素

package com.yyl.www.chapter01;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/*
* List子介面的使用
* 1.有下標,有順序
* 2.可以重複*/
public class Demo03 {
public static void main(String[] args) {
//建立物件
List list=new ArrayList<>();
//新增元素
list.add("蘋果");
list.add("小米");
list.add(0,"華為");
System.out.println("元素個數"+list.size());
System.out.println(list.toString());
//2.刪除元素
/*list.remove("蘋果");
list.remove(0);//刪除腳標為0的元素
System.out.println(list.toString());
*/
//3.遍歷
//3.1使用for遍歷
System.out.println("—————————for迴圈———————————");
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
//3.2使用增強for
System.out.println("——————————增強for———————————");
for (Object object:list) {
System.out.println(object);
}
//3.3使用迭代器
System.out.println("———————————迭代器———————————");
Iterator it= list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//3.4使用列表迭代器
//和Iterator的區別:1.ListIterator可以向前或者向後遍歷,可以新增,刪除,修改元素
ListIterator lit=list.listIterator();
System.out.println("————————使用列表迭代器——————————");
while(lit.hasNext()){//正向
System.out.println(lit.nextIndex()+":"+lit.next());
}
while(lit.hasPrevious()){//逆向,先讓指標指向最後一個元素
System.out.println(lit.previousIndex()+":"+lit.previous());
}
//4.判斷
System.out.println(list.contains("華為"));
System.out.println(list.isEmpty());
//5.獲取
System.out.println(list.indexOf("華為"));
}
package com.yyl.www.chapter01;

import java.util.ArrayList;
import java.util.List;

public class Demo04 {
public static void main(String[] args) {
List list=new ArrayList();
list.add(10);//list不能儲存基本型別,此處包含自動裝箱操作
list.add(20);
list.add(30);
list.add(40);
list.add(50);
System.out.println("元素個數"+list.size());
System.out.println(list.toString());
//2.s刪除操作
//錯誤示範:list.remove(20);
list.remove(new Integer(20));
//list.remove((Object)20);
//list.remove(0);
System.out.println("刪除元素"+list.size());
System.out.println(list.toString());
//3.補充方法subList();
List sublist=list.subList(1,3);//左閉右開
System.out.println(sublist.toString());
}
}

List實現類

ArrayList【重點】

  1. 陣列結構實現,查詢快,增刪慢

  2. jdk1.2版本,執行效率快,執行緒不安全

Vector

  1. 陣列結構實現,查詢快,增刪慢

  2. jdk1.0版本,執行效率慢,執行緒安全

LinkedList

  1. 連結串列結構實現,增刪快,查詢慢

ArrayList使用

package com.yyl.www.chapter01;
/*
* ArrayList使用:
* 1. 儲存結構:陣列,查詢遍歷快,增刪慢
* */
import java.util.*;

public class Demo05 {
public static void main(String[] args) {
//建立集合
ArrayList 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());
System.out.println(arrayList.toString());
//刪除元素
//arrayList.remove(new Student("劉德華",20));
//System.out.println("刪除之後"+arrayList.toString());
//怎麼用腳標刪除

//遍歷元素(重點)
//3.1使用迭代器
Iterator it=arrayList.iterator();
while(it.hasNext()){
System.out.println((Student)it.next());
}
//3.2列表迭代器
ListIterator lit=arrayList.listIterator();
System.out.println("——————————使用列表迭代器————————");
while(lit.hasNext()){
Student s=(Student)lit.next();
System.out.println(s.toString());
}
System.out.println("————————————逆序————————————");
while(lit.hasPrevious()){
System.out.println((Student)lit.previous());
}
//判斷
System.out.println(arrayList.contains(new Student("劉德華",20)));
System.out.println(arrayList.isEmpty());
}
}

關於contains和remove:使用object的equals方法,可以通過重寫equals方法來判斷是否包含或者刪除

@Override//重寫equals方法
public boolean equals(Object obj) {
//判斷兩個物件是否誒同一個引用
if(this==obj){
return true;
}
//判斷obj是否為null
if(obj==null){
return false;
}
//判斷是否為同一個型別
if(obj instanceof Student){
//4.強制型別轉換
Student s=(Student)obj;
//比較屬性
if(this.name.equals(s.getName())&&this.age==s.getAge()){
return true;
}
}
return false;
}

ArrayList原始碼解析

常量:

private static final int DEFAULT_CAPACITY = 10;//預設容量,沒有新增任何元素時容量為0,新增任意元素後變成10,填滿之後擴容,擴容到原來的1.5倍
transient Object[] elementData; // non-private to simplify nested class access存放元素的陣列
private int 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 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.yyl.www.chapter02;

import java.util.Enumeration;
import java.util.Vector;

/*
* 演示:Vector集合使用
* 儲存結構:陣列
* */
public class Demo01 {
public static void main(String[] args) {
Vector vector=new Vector();
//新增元素
vector.add("草莓");
vector.add("芒果");
vector.add("西瓜");
System.out.println("元素個數"+vector.size());
//遍歷
//使用列舉器
Enumeration en=vector.elements();
while(en.hasMoreElements()){
String s=(String)en.nextElement();
System.out.println(s);
}
//判斷
System.out.println(vector.contains("西瓜"));
System.out.println(vector.isEmpty());
//補充
//firstElement
//lastElement
//elementAt
//
}

LinkedList

package com.yyl.www.chapter02;

import com.yyl.www.chapter01.Student;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;

/*
* 實現LinkedList使用
* 1.儲存結構:雙向連結串列
* */
public class Demo02 {
public static void main(String[] args) {
//建立集合
LinkedList 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(0);
//System.out.println("刪除之後"+linkedList.size());

//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());
System.out.println(object);
}
//3.3使用迭代器
System.out.println("——————————迭代器———————————");
/* Iterator it=linkedList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s.toString());
}
*/
ListIterator lit=linkedList.listIterator();
while(lit.hasNext()){
System.out.println(lit.next());
}
//4.判斷
//5.獲取
System.out.println(linkedList.indexOf(s1));
}
}

泛型

  • java泛型是jdk1.5中引入的一個新特性,其本質是引數化型別,把型別作為引數傳遞

  • 常見形式有泛型類、泛型介面、泛型方法

  • 語法

    <T,...>T稱為型別佔位符,表示一種引用型別

  • 好處:1.提高程式碼的重用性

    2.防止型別轉換異常,提高程式碼的安全性

泛型類

package com.yyl.www.Generic;
/*
* 泛型類:
* 語法:類名<T>
* T是佔位符,表示一種引用型別,如果編寫多個,使用逗號隔開
*
*
* */
public class Demo01<T> {
//使用泛型
//建立變數
T t;
//不能建立泛型
//T t=new T();
//沒使用泛型介面之前,不知道泛型類是什麼類
//作為方法的引數
public void show(T t){
System.out.println(t);
}
//泛型作為方法的返回值
public T getT(){
return t;
}
}
package com.yyl.www.Generic;

public class test01 {
public static void main(String[] args) {
//使用泛型類建立物件
//注意:泛型只能使用引用型別2.不同泛型型別不能相互複製
Demo01<String> myGeneric=new Demo01<String>();
myGeneric.t="hello";
myGeneric.show("大家好");
String string=myGeneric.getT();
System.out.println(string);

Demo01<Integer> myGeneric2=new Demo01<Integer>();
myGeneric2.t=10;
myGeneric2.show(200);
Integer i=myGeneric2.getT();
System.out.println(i);
}
}

泛型介面

package com.yyl.www.Generic;
/*
* 泛型介面:
* 語法:介面名+<T>
*/
public interface Demo02<T> {
String name="張三";
//不能建立泛型
//T t=new T();
//沒使用泛型介面之前,不知道泛型類是什麼類
T server(T t);
}
package com.yyl.www.Generic;
//泛型介面實現類,重寫介面的方法
//實現泛型介面時提供泛型是什麼類
public class Demo02Impl implements Demo02<String>{
@Override
public String server(String s) {//已知泛型類別,方法改變
System.out.println(s);
return s;
}
}
package com.yyl.www.Generic;
//實現泛型類或者讓介面實現類也變成泛型類
public class Demo02Impl02<T> implements Demo02<T>{
@Override
public T server(T t) {
System.out.println(t);
return t;
}
}
package com.yyl.www.Generic;

public class test02 {
public static void main(String[] args) {
Demo02Impl impl=new Demo02Impl();
impl.server("xxxxxxxx");
Demo02Impl02 impl2=new Demo02Impl02();
impl2.server("java");

}
}

泛型方法

package com.yyl.www.Generic;
/*
* 泛型方法:
* 語法:<T> + 方法返回值型別*/
public class Demo03 {
//泛型方法
public <T> void show(T t){
System.out.println("泛型方法"+t);
}
}
package com.yyl.www.Generic;

public class test03 {
public static void main(String[] args) {
//呼叫泛型方法
Demo03 s=new Demo03();
s.show("hahha");
s.show(20);
}
}

泛型集合

  1. 概念:引數化型別、型別安全集合,強制集合元素的型別必須一致。

  2. 特點:

    • 編譯時即可檢查,而非執行時丟擲異常

    • 訪問時,不必型別轉換(拆箱);

    • 不同泛型間引用不能相互賦值,泛型不存在多型

set介面

  • 特點:無序,無下標,元素不可重複

  • 方法:全部繼承自Collection中的方法

set介面使用

HashSet【重點】

  • 基於HashCode實現元素不重複

  • 當存入元素的雜湊碼相同時,會呼叫equals進行確認,如結果為true,則拒絕後者存入

TreeSer

  • 基於排列順序實現元素不重複

hashset使用

package com.yyl.www.chapter03;

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

/*
* 測試set介面的使用
* 特點:1.無序,沒有下標
* 2.不能重複*/
public class Demo01 {
public static void main(String[] args) {
Set<String> set=new HashSet<String>();
//1.新增屬性
set.add("小米");
set.add("華為");
set.add("華為");//未新增成功
set.add("蘋果");
System.out.println("元素個數"+set.size());
System.out.println(set.toString());//無序
//刪除
//set.remove("小米");
//set.clear();
//遍歷
//3.1增強for
for (Object object:set) {
System.out.println(object);
}
//迭代器
Iterator it=set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//4.判斷
System.out.println(set.contains("小米"));
System.out.println(set.isEmpty());
}
}
  • HashSet使用: 儲存結構:雜湊表:陣列+連結串列+紅黑樹 儲存過程:1.計算儲存位置,如果位置為空,則直接儲存,如果不為空,則執行第二步 2.再執行equals,如果equals方法為true,則認為是重複元素,否則則形成連結串列

package com.yyl.www.chapter03;

public class Person {
private String name;
private int age;

public Person(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 "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;
}
}
package com.yyl.www.chapter03;

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

/*
* HashSet使用:
* 儲存結構:雜湊表:陣列+連結串列+紅黑樹
* 儲存過程:1.計算儲存位置,如果位置為空,則直接儲存,如果不為空,則執行第二步
* 2.再執行equals,如果equals方法為true,則認為是重複元素,否則則形成連結串列
* */
public class Demo02 {
public static void main(String[] args) {
//建立集合
HashSet<Person> persons=new HashSet<>();
//新增資料
Person s1=new Person("劉德華",20);
Person s2=new Person("林志玲",22);
Person s3=new Person("梁朝偉",25);
persons.add(s1);
persons.add(s2);
persons.add(s3);
persons.add(s3);//無法新增,重複,物件無法重複新增
persons.add(new Person("梁朝偉",25));//成功新增
//如何讓new的元素判斷相等,重寫hashcode方法
//重寫hashcode方法後依然加入,只是新增方式為連結串列
//重寫equals方法讓他無法新增
System.out.println(persons.toString());
//刪除
//persons.remove(s3);
persons.remove(new Person("梁朝偉",25));//同樣能刪除
System.out.println(persons.toString());
//遍歷
//使用for迴圈
for (Object object:persons) {
System.out.println(object);
}
//使用迭代器
Iterator<Person> it=persons.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//判斷
System.out.println(persons.contains(new Person("劉德華",20)));
System.out.println(persons.isEmpty());
}

#補充知識:重寫hashcode方法時使用31

  1. 31時素數,減少雜湊衝突

  2. 31計算方便,i*31=(i<<5)-i

Treeset

  1. 基於排列順序實現元素不重複

  2. 實現了SortedSet介面,對集合元素自動排序

  3. 元素物件型別必須實現Compareable介面,指定排序規則

  4. 通過CompareTo方法確定是否為重複元素

  5. 使用

    package com.yyl.www.chapter03;

    import java.util.Iterator;
    import java.util.TreeSet;

    /*
    * TreeSet的使用
    * 儲存結構:紅黑樹*/
    public class Demo03 {
    public static void main(String[] args) {
    TreeSet<String> treeSet=new TreeSet<>();
    //新增元素
    treeSet.add("xyz");
    treeSet.add("abc");
    treeSet.add("hello");//存在排序
    //treeSet.add("xyz");重複,不在新增
    System.out.println("元素個數"+treeSet.size());
    System.out.println(treeSet.toString());
    //刪除
    // treeSet.remove("xyz");
    // System.out.println(treeSet.toString());
    //遍歷
    for (Object object:treeSet) {
    System.out.println(object);
    }
    Iterator<String> it=treeSet.iterator();
    while(it.hasNext()){
    System.out.println(it.next());
    }
    //判斷
    System.out.println(treeSet.contains("xyz"));
    System.out.println(treeSet.isEmpty());
    }
    }
  6. 儲存方式

package com.yyl.www.chapter03;

import java.util.Iterator;
import java.util.TreeSet;

/*
* 使用treeSet儲存資料
* 儲存結構:紅黑樹
* 要求:元素必須實現Comparable介面,compareTo函式返回值為0則認為是重複元素
* */
public class Demo04 {
public static void main(String[] args) {
//建立集合
TreeSet<Person> treeSet=new TreeSet<>();
//新增元素
Person s1=new Person("劉德華",20);
Person s2=new Person("林志玲",22);
Person s3=new Person("梁朝偉",25);
treeSet.add(s1);
treeSet.add(s2);
treeSet.add(s3);
System.out.println(treeSet.toString());/*ClassCastException 型別轉換異常cannot be cast to java.
lang.Comparable
treeSet儲存時會自動排序,沒有給排序的規則,故無法進行排序
報出錯誤*/
//2.刪除
treeSet.remove(new Person("梁朝偉",25));//能刪除,通過compareTo函式判斷
System.out.println(treeSet.toString());
//3.遍歷
//3.1foreach增強for
for (Object object:treeSet) {
System.out.println(object);
}
//3.2迭代器
Iterator<Person> it =treeSet.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//4.判斷
}
}
  1. 補充

package com.yyl.www.chapter03;

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

/*
* TreeSet使用
* Comparator:實現定製比較(比較器)
* Comparable 可比較的*/
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 s1=new Person("劉德華",20);
Person s2=new Person("林志玲",22);
Person s3=new Person("梁朝偉",25);
Person s4=new Person("李四",25);
persons.add(s1);
persons.add(s2);
persons.add(s3);
persons.add(s4);
System.out.println(persons.toString());
}
}
  1. 案例

  2. package com.yyl.www.chapter03;

    import java.util.Comparator;
    import java.util.TreeSet;
    /*
    * 要求:使用TreeSet集合實現字串按照長度進行排序
    * 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("pinguo");
    treeSet.add("xiangjiao");
    treeSet.add("beijin");
    treeSet.add("nanjin");
    treeSet.add("lisi");
    treeSet.add("cat");
    treeSet.add("huawei");
    System.out.println(treeSet.toString());
    }
    }

Map介面

  1. 特點:儲存一對資料(Key-Value),無序、無下標、鍵不可重複,值可重複

  2. 方法

    V put(K key,V value);//將物件存入到集合中
    Object get(Object key);//根據鍵獲取對應的值
    Set<K>;//返回所有key
    Collection<V> values();//返回包含所有值的Collection集合
    Set <Map.Entry<K,V>>//鍵值匹配的Set集合

Map介面的使用

package com.yyl.www.chapter04;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/*
* Map介面的使用
* 特點:1.儲存鍵值對2.鍵不能重複3.無序*/
public class Demo01 {
public static void main(String[] args) {
//建立map集合
Map<String,String> map=new HashMap<>();
//新增元素
map.put("cn","中國");
map.put("uk","英國");
map.put("usa","美國");
map.put("cn","zhongguo");//後面新增的value覆蓋前邊的value
System.out.println(map.toString());
// map.remove("usa");
//System.out.println("刪除之後"+map.size());

//3.遍歷
//3.1使用keySet,返回值為所有key的集合
System.out.println("—————————keySet—————————");
//Set<String> keyset=map.keySet();
for(String key:map.keySet()){
System.out.println(key+"="+map.get(key));
}
//3.2使用entrySet()方法,返回值為一對key和value的Map.entry組合
//相比keySet遍歷,效率高一點
Set<Map.Entry<String,String>> entries= map.entrySet();/*此處的Entry<String,String>為Map的一
個內部介面
*/
for(Map.Entry<String,String> s:entries){
System.out.println(s.getKey()+"="+s.getValue());
}
//4.判斷
System.out.println(map.containsKey("cn"));
System.out.println(map.containsValue("泰國"));
}
}

HashMap使用(重點)

建構函式

    • HashMap() 構造一個空的 HashMap ,預設初始容量(16)和預設負載係數(0.75)。

static final int TREEIFY_THRESHOLD = 8;//hashcode判斷相等但equals判斷不相等時在同一位置新增連結串列
//當連結串列節點數大於8時,集合元素個數大於64時轉化成紅黑樹
static final int MIN_TREEIFY_CAPACITY = 64;

static final int UNTREEIFY_THRESHOLD = 6;//當樹節點小於6時轉化成連結串列
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;//hashmap初始容量大小
static final int MAXIMUM_CAPACITY = 1 << 30;//hashmap陣列最大容量
static final float DEFAULT_LOAD_FACTOR = 0.75f;//預設載入因子,使用量大於0.75時進行擴容
transient Node<K,V>[] table;//雜湊表中的陣列
transient int size;//元素個數
package com.yyl.www.chapter04;

import com.yyl.www.chapter03.Person;

import java.util.HashMap;
import java.util.Map;

/*
* HashMap使用:
* 儲存結構:雜湊表(陣列,連結串列,紅黑樹)
* 使用key的hashcode和equals作為重複的依據*/
public class Demo02 {
public static void main(String[] args) {
//建立物件
HashMap<Student,String> students=new HashMap<>();
//剛建立hashmap時沒有新增元素,table=null,size=0,目的節省空間
//新增元素
Student s1=new Student("孫悟空",100);
Student s2=new Student("豬八戒",101);
Student s3=new Student("沙悟淨",102);
students.put(s1,"上海");
students.put(s2,"北京");
students.put(s3,"杭州");
students.put(s3,"南京");
students.put(new Student("沙悟淨",102),"湖北");//重寫hashcode和equals之後覆蓋之前的value
System.out.println("元素個數"+students.size());
System.out.println(students.toString());
//2.刪除
//students.remove(s1);
System.out.println("刪除之後"+students.toString());
//3.遍歷
//使用keySet
for(Student key:students.keySet()){
System.out.println(key+"="+students.get(key));
}
//使用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.containsKey(new Student("孫悟空",100)));
System.out.println(students.isEmpty());
}
}
package com.yyl.www.chapter04;

import java.util.Objects;

public class Student {
private String name;
private int stuNo;
public Student(){

}
public Student(String name, int stuNo) {
this.name = name;
this.stuNo = stuNo;
}

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;
}

@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() &&
getName().equals(student.getName());
}

@Override
public int hashCode() {
return Objects.hash(getName(), getStuNo());
}
}

原始碼分析總結總結

  1. HashMap剛建立時,table時null,為了節省空間,當新增第一個元素時,table調整為16

  2. 當元素個數大於閾值(16*0.75=12)時,會進行擴容,擴容後大小為原來的兩倍,目的是減少調整元素個數

  3. jdk1.8 當每個連結串列長度大於等於8,並且集合元素大於64時,會調整為紅黑樹,目的提高效率

  4. jdk1.8 當連結串列長度小於6,調整成連結串列

  5. jdk1.8以前,連結串列是頭插法。jdk1.8之後是尾插法

Map結合其他實現類

  1. HashMap,jdk1.2版本,執行緒不安全,執行效率快:允許用null作為key或value

  2. HashTable,jdk1.0版本,執行緒安全,執行效率慢:不允許用null作為key和value

  3. Properties(HashMap子類):要求key和value都是String類,,通常用於配置檔案的讀取

  4. TreeMap:實現了SortedMap介面(是map的子介面),可以對key自動排序

TreeMap使用

package com.yyl.www.chapter04;
/*
* TreeMap使用:
* 儲存結構:紅黑樹*/
import java.util.Map;
import java.util.TreeMap;

public class Demo03 {
public static void main(String[] args) {
//新建集合
TreeMap<Student,String> treeMap=new TreeMap<>();//其他方法,比較器
//1.新增元素
Student s1=new Student("孫悟空",100);
Student s2=new Student("豬八戒",101);
Student s3=new Student("沙悟淨",102);
treeMap.put(s1,"北京");
treeMap.put(s2,"上海");
treeMap.put(s3,"廣州");
treeMap.put(new Student("沙悟淨",102),"南京");//學號相同認為元素相同,comparator比較規則
System.out.println("元素個數"+treeMap.size());
System.out.println(treeMap.toString());
//2.刪除元素
treeMap.remove(new Student("沙悟淨",102));
System.out.println("刪除之後"+treeMap.size());
//3.1使用KeySet
for(Student key: treeMap.keySet()){
System.out.println(key+treeMap.get(key));
}
//3.2使用entrySet
for(Map.Entry<Student,String> map: treeMap.entrySet()){
System.out.println(map.getKey()+"="+map.getValue());
}
//4.判斷
System.out.println(treeMap.containsKey(new Student("沙悟淨",102)));
System.out.println(treeMap.isEmpty());
}
}

Collection工具類

  1. 概念:集合工具類,定義除了存取以外的集合常用方法

  2. 方法:

    • public static void reverse(List<?> list);//反轉集合中元素順序

    • public static void shuffle(List<?> list);//隨機重置集合元素順序

    • public static void sort(List<?> list);//升序排序,(元素型別必須實現Comparable介面)

      package com.yyl.www.chapter04;

      import java.util.*;

      public class Demo04 {
      public static void main(String[] args) {
      List<Integer> list=new ArrayList<>();
      list.add(20);
      list.add(5);
      list.add(12);
      list.add(30);
      list.add(6);
      //1.sort
      System.out.println("排序前"+list.toString());
      Collections.sort(list);
      System.out.println("排序後"+list.toString());
      //2.binarySearch(二分查詢),先排序,再查詢
      int j=Collections.binarySearch(list,20);
      System.out.println(j);//返回key的對應位置
      //copy(複製)
      List<Integer> list2=new ArrayList<>();
      for(int i=0;i<list.size();i++){
      list2.add(0);
      }
      Collections.copy(list2,list);//必須兩個list集合大小一樣才能複製
      System.out.println(list2);
      //reverse反轉
      Collections.reverse(list);
      System.out.println("反轉之後"+list);
      //shuffe 打亂
      Collections.shuffle(list2);
      System.out.println("打亂之後"+list2);
      //補充:把list轉化成陣列
      Integer[] l=list.toArray(new Integer[0]);//當new的陣列長度小於list長度,返回list長度,若大於,則返回new的陣列長度
      System.out.println(l.length);
      System.out.println(Arrays.toString(l));
      //陣列轉化成集合
      //集合是一個受限集合,不能新增和刪除
      System.out.println("陣列轉化成集合");
      String[] names={"張三","李四","王五"};
      List<String> list3= Arrays.asList(names);
      //list3.add("zhaoliu");//轉化過來的集合無法新增
      System.out.println(list3.toString());
      //int[] nums={100,200,300,400};
      //List<int[]> list4=Arrays.asList(nums);//集合裡邊每個資料變成陣列,如何輸出?
      //把基本類轉化成集合類,需要修改為包裝型別
      Integer[] nums={100,200,300,400};
      List<Integer> list4=Arrays.asList(nums);
      System.out.println(list4.toString());
      }
      }