面試常見問題
ArrayList和LinkedList的聯系和差別
1. ArrayList是實作了基于動态數組的資料結構,LinkedList基于連結清單的資料結構。
2. 對于随機通路get和set,ArrayList覺得優于LinkedList,因為LinkedList要移動指針。
3. 對于新增和删除操作add和remove,LinedList比較占優勢,因為ArrayList要移動資料
Vector和ArrayList的聯系和差別
1、Vector是多線程安全的,而ArrayList不是,這個可以從源碼中看出,Vector類中的方法很多有synchronized進行修飾,這樣就導緻了Vector在效率上無法與ArrayList相比;
2、兩個都是采用的線性連續空間存儲元素,但是當空間不足的時候,兩個類的增加方式是不同的,很多網友說Vector增加原來空間的一倍,ArrayList增加原來空間的50%,其實也差不多是這個意思,不過還有一點點問題可以從源碼中看出,一會兒從源碼中分析。
3、Vector可以設定增長因子,而ArrayList不可以。
在說集合前我們不得不說一下數組
數組的作用:存放一組相同的資料類型(基本或對象)的資料,進而實作對資料的管理
優勢:可以快速的通過下标對數組元素進行通路,效率高
劣勢:容量實作定義好了,不能随着需求變化而擴容
是以出現了更好的集合架構
一、數組和集合的比較
數組不是面向對象的,存在明顯的缺陷,集合彌補了數組的缺點,比數組更靈活更實用,而且不同的集合架構類可适用不同場合。如下:
·1:數組能存放基本資料類型和對象,而集合類存放的都是對象的引用,而非對象本身!
·2:數組容易固定無法動态改變,集合類容量動态改變。
·3:數組無法判斷其中實際存有多少元素,length隻告訴了數組的容量,而集合的size()可以确切知道元素的個數
·4:集合有多種實作方式和不同适用場合,不像數組僅采用順序表方式
·5:集合以類的形式存在,具有封裝、繼承、多态等類的特性,通過簡單的方法和屬性即可實作各種複雜操作,大大提高了軟體的開發效率
二、Java集合主要由兩個接口派生:Collection和Map,是集合架構的根接口。
1. collection的子接口:Set:接口 ---實作類: HashSet、LinkedHashSet
2. set的子接口SortedSet接口---實作類:TreeSet
3. List:接口---實作類: LinkedList,Vector,ArrayList
4. List:有序清單,允許存放重複的元素;
實作類:
ArrayList:數組實作,查詢快,增删慢,輕量級;(線程不安全)
LinkedList:雙向連結清單實作,增删快,查詢慢 (線程不安全)
Vector:數組實作,重量級 (線程安全、使用少)
5. Set:無序集合,不允許存放重複的元素;允許使用null元素
HashSet 的背景有一個HashMap;初始化背景容量;隻不過生成一個HashSet的話,系統隻提供key的通路; 如果有兩個Key重 複,那麼會覆寫之前的;
實作類
HashSet:equals傳回true,hashCode傳回相同的整數;哈希表;存儲的資料是無序的。
LinkedHashSet:此實作與 HashSet 的不同之外在于,後者維護着一個運作于所有條目的雙重連結清單。存儲的資料是有序的。
哈希表詳解:
http://www.bianceng.cn/Programming/sjjg/200705/1126.htm
http://blog.csdn.net/feixiaoxing/article/details/6885657
http://blog.csdn.net/jdh99/article/details/8490704
6. 子接口SortedSet,對Set排序實作類 :TreeSet:使用元素的自然順序對元素進行排序,或者根據建立 set 時提供的 Comparator 進行排序;二叉樹實作的;
二叉樹詳解:
http://blog.csdn.net/luckyxiaoqiang/article/details/7518888/
http://blog.csdn.net/pony_maggie/article/details/38390513
7. Map的實作類:HashMap、TreeMap、LinkedHashMap、Hashtable等
HashMap:鍵值對,key不能重複,但是value可以重複;key的實作就是HashSet;value對應着放;允許null的鍵或值;
Hashtable:線程安全的,不允許null的鍵或值;
Properties::key和value都是String類型,用來讀配置檔案;
TreeMap:對key排好序的Map; key 就是TreeSet, value對應每個key; key要實作Comparable接口或TreeMap有自己的構造器;
LinkedHashMap: 此實作與 HashMap 的不同之處在于,後者維護着一個運作于所有條目的雙重連結清單。存儲的數
據是有序的。
接口 | 簡述 | 實作 | 操作特性 | 成員要求 |
Set | 成員不能重複 | HashSet | 外部無序地周遊成員 | 成員可為任意Object子類的對象,但如果覆寫了equals方法,同時注意修改hashCode方法。 |
TreeSet | 外部有序地周遊成員;附加實作了SortedSet, 支援子集等要求順序的操作 | 成員要求實作caparable接口,或者使用 Comparator構造TreeSet。成員一般為同一類型。 | ||
LinkedHashSet | 外部按成員的插入順序周遊成員 | 成員與HashSet成員類似 | ||
List | 提供基于索引的對成員的随機通路 | ArrayList | 提供快速的基于索引的成員通路,對尾部成員的增加和删除支援較好 | 成員可為任意Object子類的對象 |
LinkedList | 對清單中任何位置的成員的增加和删除支援較好,但對基于索引的成員通路支援性能較差 | 成員可為任意Object子類的對象 | ||
Map | 儲存鍵值對成員,基于鍵找值操作,compareTo或compare方法對鍵排序 | HashMap | 能滿足使用者對Map的通用需求 | 鍵成員可為任意Object子類的對象,但如果覆寫了equals方法,同時注意修改hashCode方法。 |
TreeMap | 支援對鍵有序地周遊,使用時建議先用HashMap增加和删除成員,最後從HashMap生成TreeMap;附加實作了SortedMap接口,支援子Map等要求順序的操作 | 鍵成員要求實作caparable接口,或者使用Comparator構造TreeMap。鍵成員一般為同一類型。 | ||
LinkedHashMap | 保留鍵的插入順序,用equals 方法檢查鍵和值的相等性 | 成員可為任意Object子類的對象,但如果覆寫了equals方法,同時注意修改hashCode方法。 | ||
IdentityHashMap | 使用== 來檢查鍵和值的相等性。 | 成員使用的是嚴格相等 | ||
WeakHashMap | 其行為依賴于垃圾回收線程,沒有絕對理由則少用 |
三、Collection常見方法
add(E e); addAll(Collection c);clear();contains(Obj o);傳回是否包含指定的元素(true false)
containsAll(Collection c)是否包含c中所有元素 isEmpty(); iterator();remove();size();toArray();傳回collection中所有元素的數組
四、集合的周遊
1、增強for循環 for(Obj o:c){syso(o)}
2、使用iterator , Iterator it=c.iterator;
while(it.hasNext()){Object o = it.next()}
3、普通循環:for(Iterator it=c.iterator();it.hasNext();){it.next() }
五、代碼執行個體
1、 ArrayList
import java.util.ArrayList;
/**
*
* 關于ArrayList的基本操作
* 其它操作感興趣的讀者可以自己結合源碼實作一下
* * @author erqing
*
*/
public class ListTest {
public static void main(String[] args) {
/* 建立一個ArrayList */
ArrayList<String> list = new ArrayList<String>();
System.out.println("初始化大小:" + list.size());
/* 添加元素 */
list.add("zzz");
list.add("egg");
list.add("hell");
list.add("child");
System.out.println("目前容量:" + list.size());
/* 将ArrayList的大小和實際所含元素的大小設定一緻 */
list.trimToSize();
/* 周遊 */
for (String string : list) {
System.out.println(string);
}
/* 在指定位置插入元素 */
list.add(2, "zhu");
for (String string : list) {
System.out.println(string);
}
System.out.println("--------------");
/* 清空list */
list.clear();
/* 周遊 */
for (String string : list) {
System.out.println(string);
}
System.out.println("--------------");
}
}
2、LinkedList
import java.util.LinkedList;
public class LinkedListTest {
public static void main(String[] args) {
/* 建立一個list */
LinkedList<Integer> list = new LinkedList<Integer>();
System.out.println(list.size());
/* 向list中添加元素 */
list.add(222);
list.add(111);
list.add(0);
list.add(3333);
list.add(8888);
System.out.println(list.size());
/* 周遊list */
for (Integer integer : list) {
System.out.println(integer);
}
/* 擷取第一個元素 ,即header的next域*/
System.out.println("第一個元素是:" + list.getFirst());
/*擷取最後一個元素,即header的previous域*/
System.out.println("最後一個元素是:"+list.getLast());
}
}
3、hashset
public static void main(String[] args) {
Set set = new HashSet();
set.add("a");
set.add("b");
System.out.println(set);
Student stu= new Student(18, "小名", 60);
set.add(stu);//調用第一個對象的hashcode方法 調 equals
set.add(new Student(19, "小明", 60));
set.add(new Student(19, "小明", 60));
set.add(new Student(20, "小明", 61));
System.out.println(set);
}
4、treeset
import java.util.ArrayList;
import java.util.HashSet;
import java.util.TreeSet;
/**
* 使用treeset存放一組學生成績
* 1、可以自動排序(系統類 自然排序)
* 2、不可重複(去重)
* 3、隻能存放一種資料類型
* ---存放到 treeset中的元素必須要具有比較能力
* 調用compareTo() 如果得到的結果為0 , 兩個元素相等
* 1 ---》排到後面
* -1 --->排到前面
*
* hashset:-->hashtable(哈希表)
* treeset:-->二叉樹,紅黑樹算法
* 每存入一個元素就會調用一次compareTo方法
* @author Administrator
*
*/
import java.util.Comparator;
/**
* 外部比較器,當系統類提供的比較規則滿足不了需求時使用
* 1、自己建立一個比較器 實作 Comprator接口 ,添加一個泛型(需要比較的資料類型)
* 2、重寫comprae方法,用來比較,參數是兩個需要比較的對象
* @author Administrator
*
*/
public class MyStrCompartor implements Comparator<String>{
@Override
public int compare(String o1, String o2) {
//按照字元串長度排序
return o1.length() - o2.length();
}
}
public class TestTreeSet02 {
public static void main(String[] args) {
//使用外部比較器,
//1 拿到比較器的對象
MyStrCompartor mcom = new MyStrCompartor();
//2在建立集合時,調用有參的構造方法,把比較器傳進去
//3、在treeset中添加元素時,會優先調用自定義比較器的方法
//treeset專用
TreeSet ts = new TreeSet(mcom);
// ts.add(20);//自動裝箱
// ts.add(1);
// ts.add(100);
// ts.add(7);
// ts.add(8);
// ts.add(100);
System.out.println(ts);
//需求:不希望按照系統的排序來排列
//自己建立一個比較規則
ts.add("xiaomi32313");
ts.add("zhangliguo5");
ts.add("asima1");
ts.add("baibaibai4");
ts.add("sansan2");
// ts.add(new Student("yushen", 19, 19));
// ts.add(new Student("xiaoming", 19, 19));
// ts.add(new Student("axiaoming1", 19, 18));
System.out.println(ts);
}
}
5、hashmap
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* HashMap的使用
* @author erqing
*
*/
public class MapTest {
public static void main(String[] args) {
/* 初始化map */
Map<String, Integer> map = new HashMap<String, Integer>();
System.out.println("HashMap的初始值:" + map.size());
System.out.println("HashMap是否為空:" + (map.isEmpty() ? "是" : "否"));
/* 想map中添加元素 */
map.put("erqing", 1);
map.put("niuniu", 2);
map.put("egg", 3);
System.out.println(map.size());
;
System.out.println("HashMap是否為空:" + (map.isEmpty() ? "是" : "否"));
/* 周遊HashMap中的元素 */
Set<String> set = map.keySet();
for (String s : set) {
System.out.println(s + " " + map.get(s) + " " + "hashcode:"
+ s.hashCode());
}
/*檢測是否含有某個Key*/
System.out.println(map.containsKey("egg"));
/*檢測是否含有某個Value*/
System.out.println(map.containsValue(2));
/*列印hashCode*/
System.out.println(map.hashCode());
}
}
/*
輸出:
HashMap的初始值:0
HashMap是否為空:是
3
HashMap是否為空:否
niuniu 2 hashcode:-1045196352
egg 3 hashcode:100357
erqing 1 hashcode:-1294670850
true
true
1955200455
*/
6、treemap
public static void main(String[] args) {
SortedMap<String, Integer> map = new TreeMap<String, Integer>();
map.put("zgg", 1);
map.put("erqing", 3);
map.put("niu", 0);
map.put("abc", 2);
map.put("aaa", 5);
// map.put(1004, new Student("04",18 ,1004));
// map.put(1005, new Student("05",18 ,1005)); 也能存new
Set<String> keySet = map.keySet();
for (String string : keySet) {
System.out.print(map.get(string)+" ");
}
}
//輸出:5 2 3 0 1
📢作者:小空和小芝中的小空
📢轉載說明:務必注明來源:https://zhima.blog.csdn.net/。
📢歡迎點贊👍收藏🌟留言📝
📢連結Q群:👪技術:204918251 👪資源:877807592