1. 程式人生 > 實用技巧 >1019. 連結串列中的下一個更大節點

1019. 連結串列中的下一個更大節點

1.變數

一、 變數
變數相當於自然語言中的代詞。比如:“您好”中的您。

a) 變數的分類

  1. 成員變數(例項變數、全域性變數)-寫在類中的
  2. 區域性變數(寫在方法中的)---隨時回收---GC—System.GC
  3. 常量 ---不可變

b) 變數有哪些規則

Java是強型別語言,在使用變數時,有既定的規則:

  1. 變數必須宣告,並初始化以後才能使用
  2. 變數必須有明確的型別
  3. 變數不能重複定義(在相同程式碼域中)
  4. 變數有作用域

二、 進位制

1.10進位制
十進位制(逢10進1)
23678(10進位制)=2 * 10000 + 3* 1000 + 6100 + 7 10 + 81
=2
10^4 + 310^3+ 610^2 + 710^1 + 8

10^0
=23678

2.二進位制

逢2進1 基數是2的進位制。
權:128 64 32 16 8 4 2 1
15 = 0000 1111
0100 0001(2進位制) = 65

4. 補碼

1000 -8
1001 -7
1010 -6
1011 -5
1100 -4
1101 -3
1110 -2
1111 -1
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
在二進位制中,符號位(最高位)為0的是正數,為1的是負數.

-1 + 1 = 0
1111 + 0001 = 0
1111
+ 0001
0000
在封閉的四位運算中,(超出4位就丟棄)

1101 -3 ~0010 + 1
0011 3 0011
計算機中正數和負數的關係是取反加一。舉例:~3 + 1 = -3(表示對3取反)
補碼運算是封閉的,運算結果保留在補碼範圍內,超出範圍就溢位。
補碼有邊界溢位風險。
4位二進位制補碼最多能表示2^4(16)個數,數的範圍是-8 7

16進位制:

0 – f
十六進位制中的一個數代表了二進位制中4位
1234567890
二進位制:01001001100101100000001011010010
十六進位制:499602d2

192

256 – 192 64
二進位制:0000000011000000
十六進位制:00c0

0xf4;(十六進位制的書寫形式)
二進位制:1111 0100
十進位制:128 + 64 + 32 + 16 + 4 = 244

三、 Java的資料型別

Java中的資料型別,分為引用型別和基本資料型別,基本型別有8種。
基本資料型別
整形:byte short int long
浮點型 float double
字元型char
布林型boolean

a) 整數型別

byte 8位 0x7f 0x80
short 16位 0x7fff 0x8000
int 32位 0x7fffffff 0x80000000
long 64 … …

b) 浮點數型別

float 32位 float的精度是23位(即能精確表達23位的數,超過就被擷取)
不精確,很少被使用。
用小數表示的資料型別

double 型別能表示64位
double精確度比int精確,但是不如long
需要注意的是:浮點數的字面量預設就是double

c) 字元型別

char 經常用到的,必須掌握,字元型別是一個16位無符號位的整數。
這個數是一個字元的unicode編碼值。
Unicode編碼值 是全球範圍內的編碼方法,編制了英文,中,日,韓,阿拉伯,希伯來等等共65535個字元.
Java中的char 的範圍是0-65535
Unicode編碼中英文部分與Ascii碼相容(ASCII表示0-128)
編碼是什麼?在計算機中不能寫字,只能有0和1表示的數。
人為規定某個數除了表示一個數還可以表示一個字元。
一個10進位制的65 代表的字元就是大寫的A。

d) 布林型別

布林型別:boolean 表示真(true)假(false)

四、 資料型別的轉換

自動型別轉換
小型別到大型別的轉換稱為自動型別轉換,是自動完成的。也叫隱式型別轉換。
一般不需要處理,規則是:符號位會自動擴充套件,負數補1,正數不0.保證補碼數值不變。

強制型別轉換
這種轉換有風險,會溢位,或者損失精度。要注意資料範圍。

陣列

陣列的宣告方式:

1.動態初始化
2.靜態初始化

動態陣列一般就理解成可以無限擴大的容器,二而靜態陣列就是一開始設定時就規定了其大小
動態初始化指在建立時,使用了new物件的方式建立:

格式為:

int arr[] =new int [4];
int []arr=new int[]{1,2,3,4};

靜態初始化個格式:

int arr[]={1,2,3,4};

動態是執行期間確定元素值,靜態是編譯期間確定元素值 ,靜態陣列一經建立不可以更改。
複製擴容的方法改變;

1.arrays.copyof(src,length);src表示陣列名,length表示長度

2.System.arraycopy(src,srcpos,dest,destpos,length);

其中
src:陣列源 (被複制)
srcpos:原陣列開始複製的位置
dest:目標陣列(當前希望複製的陣列)
destpos:目標陣列複製的位置
length:複製長度

陣列的訪問都是,從0開始,0表示陣列開始的下標
陣列定義格式

陣列輸出方式:

System.out.println(arrays.tostring(XX));

陣列排序

public class ArrSortDemo {
public static void main(String[] args) {
Integer[] ary = {2,7,9,3,6,8,1};
//1.可以使用Arrays.sort對陣列進行排序
Arrays.sort(ary);
System.out.println(Arrays.toString(ary));
//2.Comparator:是一個介面,這個介面中的compare的方法是自定義排序方法
Arrays.sort(ary,new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
System.out.println(Arrays.toString(ary));
}
}

遞迴

棧記憶體:
棧記憶體是計算機的一種資料儲存方式,是Java程序啟動的時候在記憶體中開闢的儲存空間。
棧記憶體利用遵循LIFO(後進先出)原則
Java中所有的區域性變數都在棧記憶體中分配空間(壓入),方法的引數(形參)也是區域性變數,區域性變數離開作用域時,收回(從棧記憶體中彈出)。
Java方法呼叫使用棧實現,遞迴呼叫就是棧的操作。

注意:遞迴的時候按照遞迴深度分配全部臨時變數,棧記憶體開銷極大,效能不好。
在使用遞迴呼叫的時候,切記要有跳出條件。如果沒有跳出條件,就會爆棧.

什麼時候使用遞迴?
儘可能不使用。

面向物件

什麼是Object(物件)?

Object是指一個具體的事物例項。
面向物件的定義。
首先根據客戶需求抽象出業務物件,然後對需求進行合理分層。構建相對獨立的業務模組,之後設計業務邏輯,利用多型,繼承,封裝,抽象的程式設計思想,實現業務需求,最後通過整合各個模組,達到高類聚,低耦合的效果,滿足客戶需求。

面向物件分析/面向物件設計

軟體企業廣泛採用的一項有效技術,OOAD 在設計中要對映現實生活中指定問題領域中的物件和實體。這種設計要儘可能的接近於現實,即,以最自然的方式表述實體。所以說,面向物件技術的有點就是能構建與現實世界相對應的問題模型,並且保持結構、關係、行為。

面向物件的概念

型別(類) 指一個名詞的概念
引用(變數) 指引用具體概念例項的代詞。
物件(東西) 指具體概念的個體例項
行為 指具體例項的功能/函式/方法
多型 行為或者引用,在具體情形下會發生變化的現象。
在Java中,多型多表示父類引用指向子類例項
封裝 任何物件例項都是儘可能封裝,減少暴露它的實現細節是不可見的
繼承 增強程式碼的可複用性,抽取業務功能的共性。

構造器

什麼是構造器?

構造物件的函式。
構造器的特點:
Java中的構造器(構造方法)宣告在類內部
方法名與類名一直的方法叫構造方法
構造方法不能宣告返回值型別
構造方法可以包含引數,引數一般是建立物件例項必須依賴的條件。
任何類都一定有構造器,如果程式設計師不寫構造器,JVM會自動的為該類添
一個無參構造器。
構造器過載
構造器過載指寫多個引數不一樣的構造器。

this關鍵字

指當前物件。

四、方法的過載

方法的過載是發生在同類中的,方法名一樣,方法簽名不一樣的方法,稱為過載。
方法的過載與返回值無關。
多型,功能的多樣性。

Java引數的傳遞規則

Java是基於值的傳遞,是變數值的複製.
基本型別就是其中的值的複製
引用型別就是地址值的複製

繼承

提高程式碼的複用性。抽取業務功能的共通性。
繼承中有兩個概念:
父類
用來抽取共性程式碼。
子類

• 繼承

exdents 關鍵字 是繼承的意思
Object類

Java類預設繼承於Object,任何類都繼承了Object類的所有屬性和方法,

其中有三個方法,比較重要:

1.toString()

	重寫了物件的內容。如果不重寫toString(),列印物件會打印出地址值。如果重寫toString(),將列印toString()方法返回

	的指定的字串。

2.equals();

	用來比較兩個物件是否相等的方法

	比較物件分為兩種:"引用相等"與"物件相等"

	比較引用值是否相等,使用 "=="

	比較物件是否相等,使用"equals"

	但是 equals需要被重寫,因為Object的類的equals方法就是 ==

	eques預設的比較規則是地址值的比較。

	如果覆蓋的話,請規循比較規則:

	自反性:

	對稱性:

	傳遞性:

	一致性:

3.hashCode();

	hachCode方法要與equals方法一同覆蓋(規定)

	當兩個物件equals比較為true時,應具有相同的hashCode值

	當兩個物件equals比較為false時,應具有不同的hashCode值

	hashCode值要穩定,一個物件建立以後就應該在變化。

	預設的hashCode值是當前堆物件地址值轉換的一個整數,這個整數不是記憶體地址。

	一般使用物件的OID值作為hashCode值。

	IOD是物件的唯一編號,在專案中一般採用資料庫生成IOD,也就是資料庫中的"主鍵".

重寫

重寫是發生在父類與子類之間的。

父類方法被子類方法重寫後,一定呼叫子類的。

• 多型

父類引用指向子類例項。

重寫,過載都是多型的一種。

方法動態繫結物件

屬性靜態繫結變數型別

• 繼承中的構造器

子類構造器一定預設呼叫父類無參構造器。

子類優先呼叫父類無參構造器開闢記憶體空間,所以,父類空間先載入。

• 物件的例項化過程

• 在建立類之前,檢查類是否被載入(是將硬碟上的.class檔案載入到記憶體中),如果沒有載入就載入這個類.在這個類被擠在之前要載入所有的父類。

Java執行時採用的策略:懶惰式載入(按需載入):如果第一次用到就載入,只加載一次,通過CLASSPATH指定的路徑尋找檔案(.class),載入以後是一個物件,型別Class.

• 在記憶體堆中分配物件空間。遞迴分配其所有父類和子類屬性空間。屬性預設自動初始化。

• 進行屬性賦值

• 遞迴呼叫父類構造器(無參)

• 呼叫本類構造器

• 引用型別的轉換

向上轉換(隱式/自動型別轉換),是小型別到大型別的轉換

向下轉換(強制型別轉換),是大型別到小型別的轉換

instanceof 運算子 ,用來檢查引用物件的型別,經常與引用型別的強制型別轉換配合,實現安全的型別轉換,避免型別轉換異常。

• 介面

我們使用抽象方法或者抽象類來作為系統的分析和設計的工具。用來實現客戶關係管理業務的架構。

介面的特性:

介面是特殊的抽象類

介面用來表示純抽象的概念,沒有任何具體的方法。

介面不能被例項化,可以定義變數

介面變數可以引用具體實現類的例項(多型)

介面只能被實現(繼承)一個具體類實現介面,必須實現其所有的抽象方法。

介面的屬性,預設是常量public static final

介面之間可以繼承

一個具體的類可以實現多個介面,實現多繼承現象。

介面中的方法一定是抽象方法。預設缺失public abstract xxx

實現介面,使用關鍵字implements,實際上是一種繼承關係。

• 抽象類

只有行為的概念,沒有具體的實現。

抽象類中的方法可以是抽象方法,也可以被具體化。抽象類不是純抽象概念

包含抽象方法的類一定是抽象類。抽象類不能被例項化。只能定義引用變數

訪問控制修飾符

Java中的訪問控制修飾符是修飾Java中類、屬性、方法的課間範圍。

public 任意

protected 類		包內		子類

[default] 類		包內

private	    類



同一個.java檔案當中只能有一個public修飾的類

static

靜態修飾符.

1.static修飾的資源屬於類級別,是全體物件例項共享的資源



靜態屬性

	使用static修飾,屬於整個類的屬性。

	靜態資源是在類載入期間初始化的

	靜態資源可以直接使用類名.資源名訪問。比如:System.out

例項屬性

	屬於物件的屬性

	必須要有物件才能夠訪問。

	



靜態程式碼塊是在類載入期間執行的程式碼塊,由於類只加載一次,所以靜態程式碼塊只執行一次。

一般用來在類載入以後初始化一些靜態資源的時候使用。

final

final修飾的類,不能被繼承

final修飾方法不能被重寫

final修飾的變數,初始化以後就不能再修改

JavaBean規範(開發規範)

JavaBean不是語法規範,是習慣性程式設計規範,用這個規範寫的類比較方便。

有的時候,JavaBean的類也稱為:POJO類(Plan Old Java Object)

簡化規範:

1.必須有包

	專案名、包名、類名、等路徑名,不要使用中文。

2.Java類,具有無引數構造器

3.屬性儘可能私有化,方法儘可能公開化

	屬性私有後提供set、get方法。

4.必須實現序列化介面



JDK提供的類幾乎都符合JavaBean規範。

一、String 字串

String是一個API提供的類,存放字串。底層是char[]String字面量相同時,會替換為同一個String物件的引用。常量連線的結果也被優化為一個字串.
String比較的時候用equals

解析:

在字串當中使用加號(a+=b)可以對字串進行拼接
也可以使用StringfBuffer類進行拼接,元素插入
例如:

	buider.append("李敖先生").append("的前妻").append("胡因夢女士").insert(0, "大師").append("據說十分漂亮").delet(4, 6);
	System.out.println(buider);

相比較String而言StringBuffer的效能更加高效
可以通過:
System.currentTimeMillis();
對比如二者效率

二、靜態字串

Java編譯期間(javac),凡是字面量和常量的運算,都會先算出結果
執行期當字串池有String"字面量"時,Java會直接用,如果沒有才建立。
""就是一個物件 String是一個特殊的類

三、API

	length()		返回字串的長度
	trim();			去除前後兩端的空白 \n \t \s
	toLoweCase()	將字串變為小寫
	toUpperCase()	將字串變為大寫
	indexOf(String str) 根據指定的字串返回下標		
	lastIndexof()	返回最後一次出現的指定字元的下標位置
	endsWith()		是否已指定的字尾結尾
	startsWith()	是否已指定的字首開始
	subString(int start,int end)	擷取一段子字串(包前不包後)
	subString(int start)		擷取一段子字串(包前不包後)
	tocharArray()	將字串轉換成一個數組
	split()			根據既定的字元進行分割字串
	equalsIgnoreCase() 忽略大小寫比較

四、StringBuilder、StringBuffer

StringBuilder內部也是對char陣列的操作,但是陣列內容是可變的,如果長度不夠,利用陣列邊長演算法來維護
自動擴容長度。

StringBuffer 是執行緒安全的,速度比較慢
StringBuilder 非執行緒安全的,速度比較快

StringBuilder與StringBuffer API幾乎一模一樣

五、日期

Date
	long + 操作(很多API的方法已經過時了。有BUG)
Calender
	long + 操作(一般情況都使用Calender)
	 Date內部維護著一個long值
	 即:1970年至今的毫秒數
	
	Date date = new Date();
	System.out.println(date);
		
	long time = date.getTime();
	System.out.println(System.currentTimeMillis());
	System.out.println(time);
SimpleDateFormat
	Date + 操作  (日期格式的操作)

解析:

		System.out.println(dt);

六 一、集合

集合底層就是陣列
集合的底層就是物件陣列 = Object[] objs = new Object[n];

List

LinkedList		

LinkedList實現了List介面,能進行佇列操作。
LinkedList實現了Deque介面, 能當做雙端佇列使用。(即:頭,尾操作,類似於棧)
#### 解析:  
		/****************基本操作**********************/
		linkedList.addFirst(0);//新增元素到列表開頭
		linkedList.add(1);//在列表結尾新增元素
		linkedList.add(2, 2);//在指定位置新增元素
		linkedList.addLast(3);//新增元素到列表結尾
		System.out.println("linkedList:" + linkedList);	
		//獲取資料
		System.out.println("getFirst():" +linkedList.getFirst());//返回集合中第一個元素
		System.out.println("getLast():" + linkedList.getLast());//返回集合中的最後一個元素
		System.out.println("removeFirst():" + linkedList.removeFirst());//移除並返回集合中的第一個元素
		System.out.println("removeLast():" + linkedList.removeLast());//移除並返回集合中的最後一個元素
		System.out.println("linkedList:" + linkedList);
		System.out.println("contains(1):" + linkedList.contains(1));//判斷此集合中指定的元素,如果包含返回true 否則false  
       位置訪問操作
		System.out.println("------------------------------------------------");
		
		linkedList.set(1, 3);//將此集合中指定位置的元素替換成指定的元素
		System.out.println("After set :" + linkedList);
		
		System.out.println(linkedList.get(1));//獲取指定下標位置的元素
		
		linkedList.add(3);
		System.out.println("linkedList:" + linkedList);
		System.out.println("indexOf(3):" + linkedList.indexOf(3));//返回集合中首次出現的指定元素的索引
		System.out.println("lastIndexOf(3):" + linkedList.lastIndexOf(3));////返回集合中最後一次出現的指定元素的索引
	
		/*****************Queue操作***********************/
		System.out.println("------------------------------------------");
		//linkedList.clear();//清除集合中所有的元素
		System.out.println(linkedList.peek());   //獲取但不移除此列表的頭
		System.out.println(linkedList.element());//獲取但不移除此列表的頭
		//linkedList.clear();//清除集合中所有的元素
		/*
		 * poll()與remove()差異在於poll返回null remove 拋異常
		 */
		System.out.println("poll():" + linkedList.poll());//獲取並移除此列表的頭
		System.out.println("After poll :" + linkedList);
		System.out.println("remove():" + linkedList.remove());//獲取並移除此列表的頭
		System.out.println("After remove :" + linkedList);
		
		System.out.println("linkedList:" + linkedList);
		linkedList.offer(4);//新增元素到列表結尾
		System.out.println("linkedList:" + linkedList);
		
		linkedList.offerFirst(2);//在此列表的開頭插入指定元素
		System.out.println("linkedList:" + linkedList);
		linkedList.offerLast(5);//在此列表的結尾插入指定元素
		System.out.println("linkedList:" + linkedList);
		
		System.out.println("-------------------------------------------");
		System.out.println(linkedList.peekFirst());//獲取但不移除此列表的頭
		System.out.println("linkedList:" + linkedList);
		System.out.println(linkedList.peekLast());//獲取但不移除此列表的尾部
		
		linkedList.pollFirst();//獲取並且移除此列表的頭
		linkedList.pollLast();//獲取並且移除此列表的尾部
		
		linkedList.push(2);//將元素推入此列表所表示的堆疊(插入到列表的頭)
		System.out.println("linkedList:" + linkedList);
		linkedList.pop();//從此列表所表示的堆疊彈出一個元素(獲取並移除第一個元素)
		System.out.println("linkedList:" + linkedList);
		
		linkedList.add(3);
		linkedList.removeLastOccurrence(3);//從此列表中移除最後一次出現的指定的元素(遍歷)
		System.out.println("linkedList:" + linkedList);
		
		
		/**********************遍歷操作***********************/
		System.out.println("----------------------------");
		
		linkedList.clear();
		
		for (int i = 0; i < 1000000; i++) {
			linkedList.add(i);
		}
		
		//迭代器遍歷
		long start = System.currentTimeMillis();
		//獲取迭代器
		Iterator<Integer> iterator = linkedList.iterator();
		/*
		 * hasNext():判斷集合中有沒有元素,如果有返回true 否則false
		 */
		while(iterator.hasNext()) {
			iterator.next();
		}
		
		long end  = System.currentTimeMillis();
		System.out.println("iterator:" + (end - start) + "ms");
		
		//順序迭代(隨機遍歷)
/*		start = System.currentTimeMillis();
		for (int i = 0; i <linkedList.size(); i++) {
			linkedList.get(i);
		}
		end  = System.currentTimeMillis();
		System.out.println("for:" + (end - start) + "ms");*/
		
		//foreach迴圈迭代
		start = System.currentTimeMillis();
		for (Integer integer : linkedList) {}
		end  = System.currentTimeMillis();
		System.out.println("foreach:" + (end - start) + "ms");
		
		LinkedList<Integer> temp = new LinkedList<>();
		temp.addAll(linkedList);
		
		//通過pollFirst或者pollLast來遍歷
		start = System.currentTimeMillis();
		while(linkedList.size()!=0) {
			linkedList.pollFirst();
		}
		end  = System.currentTimeMillis();
		System.out.println("pollFirst:" + (end - start) + "ms");
		System.out.println(linkedList);
		//通過removeFirst或者removeLast來遍歷
		start = System.currentTimeMillis();
		while(temp.size()!=0) {
			temp.removeFirst();
		}
		end  = System.currentTimeMillis();
		System.out.println("removeFirst:" + (end - start) + "ms");
		
		
	}
ArrayList
ArrayList底層是由陣列支援,而LinkedList是由雙向連結串列支援的,其中的每個物件包含資料的同時
還包含指向連結串列中前一個與後一個元素的引用.
線性演算法。
``` ArrayList<String> list = new ArrayList<>();
	list.add("one");
	list.add("two");
	list.add("three");
	list.add("four");
	System.out.println(list);
	list.remove(2);
	System.out.println(list);
	list.add(0, "aaa");
	System.out.println(list);
	
	String one = list.get(1);//獲取指定下標所對應的元素
	System.out.println(one);
	
	list.set(1, "2");
	System.out.println(list);
	
	String old = list.remove(1);
	System.out.println(old);
	System.out.println(list);
	
	//contains 檢視此集合中是否包含指定的元素,如果有 true 否則false
	boolean flag = list.contains("aaa");
	System.out.println(flag);
	
	//isEmpty() 檢索次列表是否為空
	boolean f = list.isEmpty();
	System.out.println(f);
	
	System.out.println(list);
	//擷取一個子集合,按照包前不包後的原則
	List<String> list2 = list.subList(1, 2);
	System.out.println(list2);
	List<String> list3 = new ArrayList<>();
	list3.add("5");
	list3.add("6");
	list.addAll(list3);
	System.out.println(list);
}
``` 		List<User> list = new ArrayList<>();
		
		User u1 = new User("Tom", "123456");
		User u2 = new User("Tom", "123456");
		User u3 = new User("Tom", "123456");
		System.out.println(u1.equals(u3));//true
		list.add(u1);
		list.add(u2);
		
		System.out.println(list);
		boolean f = list.remove(new User("Tom", "123456"));
		System.out.println(f);
		System.out.println(list);
		
		
		boolean f2 = list.contains(new User("Tom", "123456"));
		System.out.println(f2);//true
		
		/**************************/
		LinkedList<User> linkedList = new LinkedList<>();
		linkedList.add(u1);
		linkedList.add(u2);
		System.out.println(linkedList);
		boolean f3 = linkedList.contains(new User("Tom", "123456"));
		System.out.println(f3);//true
		/*
		 * LinkedList中 如果方法中包含First或者last 都不會去隱含呼叫equals和hashCode
		 */
		
	}

一 Hashset集合

這是一個無序去重的集合,在它的內部不存在重複的資料,這個原理基於
equalsHashset
雖然它是無序的,但是TreeMap彌補了這個缺陷
TreeMap <Integer>tree =new TreeSet<>();
Set集合的實現類是HashSet() 與Arraylist區別是:演算法不同
但是2個類都是繼承與Collection。
假如有一個數組,裡面包含重複的元素,你可以按照下面的形式進行元素去重

Set <String>stes =new Hashset<>(names);
System.out.println(stes);

陣列轉集合

String []names={"tom","bob","bob"};
listlist =Array.alist(names);
System.....//輸出

list.add("???");  
list.remove("???");//可以傳入下標或者字串  
list.get(0);//獲取某個下標值  
list.set(0,"???");//修改某個下標的值  
list.contains("???");//判斷集合內是否有這個元素
Collections.sort();//排序
Collections.shuffle();//隨機置換,可用於撲克牌

集合轉陣列

Object[]objs=list2.toArray();//無指定型別  
String[]names=list.toArray(new String[]{});//轉換成指定型別的陣列

二、Map集合

Map集合是一個獨立的集合不繼承與Collection
HashTable() 是jdk1.0提供的,是執行緒安全的,效能比較慢
HashMap()   是jdk1.2提供的,是非執行緒安全的,效能相對於來說快一些。
Map<String, String> maps = new HashMap<String, String>();
	maps.put("3866", "董大炮");
	maps.put("8888", "劍");
	maps.put("88888", "Andi");
	maps.put("8888", "劍");
	System.out.println(maps);
	System.out.println(maps.get("3866"));
	System.out.println(maps.size());
	
	Set<Entry<String, String>> setMap =  maps.entrySet();//遍歷map
	System.out.println(setMap);
	System.out.println(setMap.iterator().next());
	System.out.println(setMap.iterator().next().getKey());//列印Key
	System.out.println(setMap.iterator().next().getValue());//列印值
	
	
	Set<String> set = maps.keySet();
	System.out.println(set);
	Collection<String> cs =  maps.values();
	System.out.println(cs);
	
	//根據key刪除元素,返回被刪除的value
	String rvalue = maps.remove("8888");
	System.out.println(rvalue);
	System.out.println(maps);
	//判斷是否有指定的key
	System.out.println(maps.containsKey("38661"));
	//判斷是否有指定的value
	System.out.println(maps.containsValue("Andis"));
	
	
	Map<Integer, Student> stuMap = new HashMap<>();
	stuMap.put(1, new Student("Jerry", 18));
	stuMap.put(2, new Student("Jerry", 18));
	System.out.println(stuMap);//hashMap中的元素重複與否與key相關,key的底層就是Set  

map集合應用,統計字串當中,每一個字出現的次數	
public static void main(String[] args) {
	// TODO Auto-generated method stub
	NumberFormat number =NumberFormat.getInstance();
	String s="如果你是在一個面臨美國製裁的國家使用GitHub的線上服務,你的賬號可能會因此被限制只能使用最基本的產品。GitHub 本週告訴居住在克里米亞的21歲俄羅斯公民 Anatoliy Kashkin,由於美國的貿易管制,它“限制”了他的 GitHub 賬戶。Anatoliy Kashkin 在 YC 上發了帖子說明此事,據說與該開發者同一地區的其他開發者也同樣被限制。GitHub 確實為開發者提供了一個爭議限制的申訴表格,但 Kashkin 聲稱通過上訴限制沒有任何好處:“這是毫無意義的。我的帳戶被標記為限制,為了取消標記,我必須提供一份證據證明我不住在克里米亞。我實際上是一名克里米亞人註冊的俄羅斯公民,我身處其中克里米亞,我一生都住在克里米亞。”";
System.out.println(s);

 Count(s);
 }
public static void Count(String s)
 {
	int count = 0 ;
	String sss=null;
	NumberFormat number =NumberFormat.getInstance();
	HashMap<Character,Integer> map =new HashMap<>();
	int point;
	for (int i = 0; i <s.length() ; i++)
	{
		if(!map.containsKey(s.charAt(i)))
		{
			map.put(s.charAt(i),1);
			}else {
				 count = map.get(s.charAt(i));
				count++;
				map.put(s.charAt(i),count);
				
			 	
				}
	
		 sss=number.format((float)map.get(s.charAt(i))/(float)s.length()*100);	
		System.out.println(sss);
		
		}
	System.out.println(map);
System.out.println("\r");
}

三、集合的繼承結構

				Collection
			
		List					Set								Map
		
	
ArrayList	LinkedList		HashSet	SortedSet				HashMap		HashTable		SortedMap
								
									TreeSet								Properties		TreeMap
以上是集合的繼承結構,請務必知悉。

四、集合的複製

Java預設的複製規則是淺層複製
集合複製有2種形式
1.clone()  是Object定義的.一般API都重寫了這個方法
2.使用複製構造器
	List<Entry<String, Object>> lists = new ArrayList<>(map.entrySet());

五、同步化(執行緒安全)

Collections.synchronizedList(list)
可以將非執行緒安全的list包裝為一個執行緒安全的
如果將一個非執行緒安全的list包裝為一個執行緒安全的轉換以後就相當於Vector

Collections.synchronizedMap(Map)
可以將非執行緒安全的Map包裝為一個執行緒安全的