Java中的一些零星容易被忽略的API(及时补充)
關于Java中的Arrays.copyOfRange()方法
要使用這個方法,首先要import java.util.*;
Arrays.copyOfRange(T[]original,int from,int to)
將一個原始的數(shù)值original,從小標from開始復制,復制到小標to,生成一個新的數(shù)組(注意這里包括下標from,不包括下標to)
這個方法在一些處理數(shù)組的編程題里很好用,效率和clone基本一致,都是native method,比利用循環(huán)復制數(shù)組效率要高得多。
?
Java String charAt()方法
此方法返回位于字符串的指定索引處的字符。該字符串的索引從零開始。
1 public class Test { 2 3 public static void main(String args[]) { 4 String s = "Strings are immutable"; 5 char result = s.charAt(8); 6 System.out.println(result); 7 } 8 }這結果:a
java之從字符串比較到==和equals方法區(qū)別
我們先看代碼
| String str1 = new String("hello"); String str2 = "hello"; ? System.out.println("str1==str2: " + (str1==str2));? \\1 System.out.println("str1.equals(str2): " + str1.equals(str2));? \\2 |
輸出結果:
| str1==str2: false str1.equals(str2): true |
關于==和equals,我們需要知道java中的數(shù)據(jù)類型,可分為兩類:
1.基本數(shù)據(jù)類型,也稱原始數(shù)據(jù)類型。byte,short,char,int,long,float,double,boolean
他們之間的比較,應用雙等號(==),比較的是他們的值。
2.復合數(shù)據(jù)類型(類)
當他們用(==)進行比較的時候,比較的是他們在內存中的存放地址,所以,除非是同一個new出來的對象,他們的比較后的結果為true,否則比較后結果為false。 JAVA當中所有的類都是繼承于Object這個基類的,在Object中的基類中定義了一個equals的方法,這個方法的初始行為是比較對象的內存地 址,但在一些類庫當中這個方法被覆蓋掉了,如String,Integer,Date在這些類當中equals有其自身的實現(xiàn),而不再是比較類在堆內存中的存放地址了。
對于復合數(shù)據(jù)類型之間進行equals比較,在沒有覆寫equals方法的情況下,他們之間的比較還是基于他們在內存中的存放位置的地址值的,因為Object的equals方法也是用雙等號(==)進行比較的,所以比較后的結果跟雙等號(==)的結果相同。
因為string屬于符合數(shù)據(jù)類型,所以應該是使用equals,假如我們使用==比較,肯定是比較它們的內存地址了,所以\\1 \\2 的結果顯而易見了
要想判斷兩個對象是否相等,不能通過比較兩個對象的引用是否相等,這是永遠都得不到相等的結果的,因為兩個對象的引用永遠不會相等,所以正確的比較方法是直接比較這兩個對象,比較這兩個對象的實質是不是一樣的,即這兩個對象里面的內容是不是相同的,通過比較這兩個對象的屬性值是否相同而決定這兩個對象是否相等。
Object類提供了一個equals()方法來比較兩個對象的內容是否相同,因此我們可以采用這個方法去比較兩個對象是否在邏輯上“相等”。如:c1.equals(c2);這里是調用從Object類繼承下來的equals()方法,通過查閱API文檔得到Object類里的equals方法的定義如下:
public boolean equals(Object obj)
注意,在重寫equals方法時,需要按照以下幾個規(guī)則設計:
1自反性 :對任意引用值X,x.equals(x)的返回值一定為true.
2對稱性: 對于任何引用值x,y,當且僅當y.equals(x)返回值為true時,x.equals(y)的返回值一定為true;
3傳遞性:如果x.equals(y)=true, y.equals(z)=true,則x.equals(z)=true
4一致性:如果參與比較的對象沒任何改變,則對象比較的結果也不應該有任何改變
5非空性:任何非空的引用值X,x.equals(null)的返回值一定為false
?再看代碼:
| String str2 = "hello"; String str3 = "hello"; System.out.println("str3==str2: " + (str3==str2));? \\3 System.out.println("str3.equals(str2): " + str3.equals(str2));? \\4 |
輸出結果:
| str3==str2: true str3.equals(str2): true |
這里的又為什么都是輸出true呢,因為它們都是從緩沖池取出來的,由于string類比較特殊,jdk專門做了緩存優(yōu)化。
原來Java運行時會維護一個String Pool(String池)。String池用來存放運行時中產生的各種字符串,并且池中的字符串的內容不重復。而一般對象不存在這個緩沖池,并且創(chuàng)建的對象僅僅存在于方法的堆棧區(qū)。
也就是說需要看string創(chuàng)建的方式:
1 當使用任何方式來創(chuàng)建一個字符串對象s時,Java運行時(運行中JVM)會拿著這個X在String池中找是否存在內容相同的字符串對象,如果不存在,則在池中創(chuàng)建一個字符串s,否則,不在池中添加。
2 Java中,只要使用new關鍵字來創(chuàng)建對象,則一定會(在堆區(qū)或棧區(qū))創(chuàng)建一個新的對象。
3 使用直接指定或者使用純字符串串聯(lián)來創(chuàng)建String對象,則僅僅會檢查維護String池中的字符串,池中沒有就在池中創(chuàng)建一個,有則罷了!但絕不會在堆棧區(qū)再去創(chuàng)建該String對象。
4 使用包含變量的表達式來創(chuàng)建String對象,則不僅會檢查維護String池,而且還會在堆棧區(qū)創(chuàng)建一個String對象。
另外,String的intern()方法是一個本地方法,定義為public native String intern(); intern()方法的價值在于讓開發(fā)者能將注意力集中到String池上。當調用 intern 方法時,如果池已經包含一個等于此 String 對象的字符串(該對象由 equals(Object) 方法確定),則返回池中的字符串。否則,將此 String 對象添加到池中,并且返回此 String 對象的引用。
java中棧和隊列的實現(xiàn)和API的用法(詳解)
一、棧的實現(xiàn)
棧的實現(xiàn),有兩個方法:一個是用java本身的集合類型Stack類型;另一個是借用LinkedList來間接實現(xiàn)Stack。
1.Stack實現(xiàn)
直接用Stack來實現(xiàn)非常方便,常用的api函數(shù)如下:
boolean??????? isEmpty() // 判斷當前棧是否為空
synchronized E??????? peek() //獲得當前棧頂元素
synchronized E??????? pop() //獲得當前棧頂元素并刪除
???????????? E??????? push(E object) //將元素加入棧頂
synchronized int????? search(Object o)? //查找元素在棧中的位置,由棧低向棧頂方向數(shù)2.LinkedList實現(xiàn)
LinkedList 是一個繼承于AbstractSequentialList的雙向鏈表。它也可以被當作堆棧、隊列或雙端隊列進行操作。
LinkedList 實現(xiàn) List 接口,能對它進行隊列操作。
LinkedList 實現(xiàn) Deque 接口,即能將LinkedList當作雙端隊列使用。
當LinkedList被當做棧來使用時,常用api及對應關系如下:
棧方法??????? 等效方法
push(e)????? addFirst(e)
pop()??????? removeFirst()
peek()?????? peekFirst()????? isEmpty()? //判斷是否為空
二、隊列的實現(xiàn)
java中雖然有Queue接口,單java并沒有給出具體的隊列實現(xiàn)類,而Java中讓LinkedList類實現(xiàn)了Queue接口,所以使用隊列的時候,一般采用LinkedList。因為LinkedList是雙向鏈表,可以很方便的實現(xiàn)隊列的所有功能。
Queue使用時要盡量避免Collection的add()和remove()方法,而是要使用offer()來加入元素,使用poll()來獲取并移出元素。它們的優(yōu)點是通過返回值可以判斷成功與否,add()和remove()方法在失敗的時候會拋出異常。 如果要使用前端而不移出該元素,使用element()或者peek()方法。
java中定義隊列 一般這樣定義: Queue<E> queue = new LinkedList<E>();
當采用LinkedList來實現(xiàn)時,api的使用和對用關系如下:
隊列方法?????? 等效方法
offer(e)????? offer(e)/offerLast(e)? //進隊列,將元素加入隊列末尾
poll()??????? poll()/pollFirst()? //獲取隊列頭的元素并移除
peek()??????? peek()/peekFirst()? //獲取隊列頭的元素?????? isEmpty() //判斷是否為空
collections在java中的常見用法
1) 排序(Sort)
使用sort方法可以根據(jù)元素的自然順序 對指定列表按升序進行排序。列表中的所有元素都必須實現(xiàn) Comparable 接口。此列表內的所有元素都必須是使用指定比較器可相互比較的
| double array[] = {112, 111, 23, 456, 231 }; for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); } Collections.sort(list); for (int i = 0; i < array.length; i++) { System.out.println(li.get(i)); } //結果:112,111,23,456,231 |
2) 混排(Shuffling)
混排算法所做的正好與 sort 相反: 它打亂在一個 List 中可能有的任何排列的蹤跡。也就是說,基于隨機源的輸入重排該 List,這樣的排列具有相同的可能性(假設隨機源是公正的)。這個算法在實現(xiàn)一個碰運氣的游戲中是非常有用的。例如,它可被用來混排代表一副牌的 Card 對象的一個 List .另外,在生成測試案例時,它也是十分有用的。
| Collections.Shuffling(list) double array[] = {112, 111, 23, 456, 231 }; for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); } Collections.shuffle(list); for (int i = 0; i < array.length; i++) { System.out.println(li.get(i)); } //結果:112,111,23,456,231 |
3) 反轉(Reverse)
使用Reverse方法可以根據(jù)元素的自然順序 對指定列表按降序進行排序。
| Collections.reverse(list) double array[] = {112, 111, 23, 456, 231 }; for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); } Collections. reverse (list); for (int i = 0; i < array.length; i++) { System.out.println(li.get(i)); } //結果:231,456,23,111,112 |
4) 替換所有的元素(Fill)
使用指定元素替換指定列表中的所有元素。
| String str[] = {"dd","aa","bb","cc","ee"}; for(int j=0;j li.add(new String(str[j])); } Collections.fill(li,"aaa"); for (int i = 0; i < li.size(); i++) { System.out.println("list[" + i + "]=" + li.get(i)); } //結果:aaa,aaa,aaa,aaa,aaa |
5) 拷貝(Copy)
用兩個參數(shù),一個目標 List 和一個源 List, 將源的元素拷貝到目標,并覆蓋它的內容。目標 List 至少與源一樣長。如果它更長,則在目標 List 中的剩余元素不受影響。
Collections.copy(list,li): 后面一個參數(shù)是目標列表 ,前一個是源列表
| double array[] = {112, 111, 23, 456, 231 }; List list = new ArrayList(); List li = new ArrayList(); for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); } double arr[] = {1131,333}; String str[] = {"dd","aa","bb","cc","ee"}; for(int j=0;j li.add(new Double(arr[j])); } Collections.copy(list,li); for (int i = 0; i System.out.println("list[" + i + "]=" + list.get(i)); } //結果:1131,333,23,456,231 |
6) 返回Collections中最小元素(min)
根據(jù)指定比較器產生的順序,返回給定 collection 的最小元素。collection 中的所有元素都必須是通過指定比較器可相互比較的
| Collections.min(list) double array[] = {112, 111, 23, 456, 231 }; List list = new ArrayList(); for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); } Collections.min(list); for (int i = 0; i System.out.println("list[" + i + "]=" + list.get(i)); } //結果:23 |
7) 返回Collections中最大元素(max)
根據(jù)指定比較器產生的順序,返回給定 collection 的最大元素。collection 中的所有元素都必須是通過指定比較器可相互比較的
| Collections.max(list) double array[] = {112, 111, 23, 456, 231 }; List list = new ArrayList(); for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); } Collections.max(list); for (int i = 0; i System.out.println("list[" + i + "]=" + list.get(i)); } //結果:456 |
?
總結
以上是生活随笔為你收集整理的Java中的一些零星容易被忽略的API(及时补充)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 探秘Java中的String、Strin
- 下一篇: Java中的比较器