java 集合数据类型_Java基础知识(数据类型和集合)
一、數(shù)據(jù)類型
包裝類型
包裝類型是對基本數(shù)據(jù)類型不足之處的補(bǔ)充。
基本數(shù)據(jù)類型的傳遞方式是值傳遞,而包裝類型是引用傳遞,同時(shí)提供了很多數(shù)據(jù)類型間轉(zhuǎn)換的方法。
Java1.5 以后可以自動(dòng)裝箱和拆箱
二、集合
List:有序、可重復(fù)。可以通過索引快速查找,但進(jìn)行增刪操作時(shí)后續(xù)的數(shù)據(jù)需要移動(dòng),所以增刪速度慢。?List 接口的大小可變數(shù)組的實(shí)現(xiàn),即:可以直接指定容量大小
|--ArrayList:底層數(shù)據(jù)結(jié)構(gòu)是 數(shù)組結(jié)構(gòu).是線程不同步的(不安全的).查詢速度很快,但是增刪較慢。
構(gòu)造一個(gè)初始容量為 10 的空列表,當(dāng)放滿了10個(gè)元素后,以50%的長度加長集合容器的長度。
|--LinkedList:底層數(shù)據(jù)結(jié)構(gòu)是 鏈表結(jié)構(gòu)。對元素的增刪速度很快。但是查詢速度很慢。線程是不同步的。
|--Vector:底層數(shù)據(jù)結(jié)構(gòu)也是數(shù)組結(jié)構(gòu),是線程同步的(安全的),效率低,被ArrayList替代了。1.2版本以后的集合都是不同步的;當(dāng)放滿了10個(gè)元素后,以100%的長度加長集合容器的長度。
Vector的特有功能
1、添加功能
public void addElement(Object obj)
2、獲取功能
public Object elementAt(int index)
public Enumeration elements()
LinkedList的特有功能
1、添加功能
public void addFirst(Object e)
public void addLast(Object e)
2、獲取功能
public Object getFirst()
public Object getLast()
3、刪除功能
public Object removeFirst()
public Object removeLast()
ArrayList和LinkedList的區(qū)別
ArrayList擴(kuò)容是將就得數(shù)組復(fù)制到新的數(shù)組的過程,所以會(huì)時(shí)間損耗是復(fù)制移動(dòng)的時(shí)間,空間損耗是新的數(shù)組是按1.5倍擴(kuò)容,復(fù)制移動(dòng)完數(shù)據(jù)可能會(huì)有剩余空間浪費(fèi)
1.ArrayList是實(shí)現(xiàn)了基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),每個(gè)元素在內(nèi)存中存儲(chǔ)地址是連續(xù)的;LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu),每個(gè)元素內(nèi)容包擴(kuò)previous, next, element(其中,previous是該節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn),next是該節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn),element是該節(jié)點(diǎn)所包含的值),也是由于這一性質(zhì)支持了每個(gè)元素在內(nèi)存中分布存儲(chǔ)。
2.為了使得突破動(dòng)態(tài)長度數(shù)組而衍生的ArrayList初始容量為10,每次擴(kuò)容會(huì)固定為之前的1.5倍,所以當(dāng)你ArrayList達(dá)到一定量之后會(huì)是一種很大的浪費(fèi),并且每次擴(kuò)容的過程是內(nèi)部復(fù)制數(shù)組到新數(shù)組;LinkedList的每一個(gè)元素都需要消耗一定的空間
3.對于每個(gè)元素的檢索,ArrayList要優(yōu)于LinkedList。LinkedList不 支持高效的隨機(jī)元素訪問;因?yàn)锳rrayList從一定意義上來說,就是復(fù)雜的數(shù)組,所以基于數(shù)組index的? 檢索性能顯然高于通過for循環(huán)來查找每個(gè)元素的LinkedList。
4.元素插入刪除的效率對比,要視插入刪除的位置來分析,各有優(yōu)劣
在列表首位添加(刪除)元素,LnkedList性能遠(yuǎn)遠(yuǎn)優(yōu)于ArrayList,原因在于ArrayList要后移(前移)每個(gè)元素的索引和數(shù)組擴(kuò)容(刪除元素時(shí)則不需要擴(kuò)容)。(測試的時(shí)候當(dāng)然插入一次是看不出來什么的,我自己測試插入十萬次,就會(huì)有數(shù)組擴(kuò)容arraycopy的因素)而LinkedList則直接增加元素,修改原第一元素該節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn)即可,刪除同理
在列表中間位置添加(刪除)元素,總的來說位置靠前則LnkedList性能優(yōu)于ArrayList,靠后則相反。出現(xiàn)這種情況的原因在于ArrayList性能主要損耗在后移(前移)該位置之后的元素索引,而LinkedList損耗在for循環(huán)從第一位檢索該位置的元素。這個(gè)性能反轉(zhuǎn)的臨界點(diǎn)不固定,我自己測試插入十萬次,在15000次左右損耗時(shí)間相比出現(xiàn)變化
在列表末尾位置添加(刪除)元素,性能相差不大。
Set:無序、不可重復(fù)。
Collection
|--List
有序(存儲(chǔ)順序和取出順序一致),可重復(fù)
|--Set
無序(存儲(chǔ)順序和取出順序不一致),唯一
HashSet:它不保證 set 的迭代順序;特別是它不保證該順序恒久不變。
注意:雖然Set集合的元素?zé)o序,但是,作為集合來說,它肯定有它自己的存儲(chǔ)順序,
而你的順序恰好和它的存儲(chǔ)順序一致,這代表不了有序,你可以多存儲(chǔ)一些數(shù)據(jù),就能看到效果。
HashSet的唯一性
問題:為什么存儲(chǔ)字符串的時(shí)候,字符串內(nèi)容相同的只存儲(chǔ)了一個(gè)呢?
通過查看add方法的源碼,我們知道這個(gè)方法底層依賴 兩個(gè)方法:hashCode()和equals()。
步驟:
首先比較哈希值
如果相同,繼續(xù)走,比較地址值或者走equals()
如果不同,就直接添加到集合中
按照方法的步驟來說:
先看hashCode()值是否相同
相同:繼續(xù)走equals()方法
返回true: 說明元素重復(fù),就不添加
返回false:說明元素不重復(fù),就添加到集合
不同:就直接把元素添加到集合
如果類沒有重寫這兩個(gè)方法,默認(rèn)使用的Object()。一般來說不同相同。
而String類重寫了hashCode()和equals()方法,所以,它就可以把內(nèi)容相同的字符串去掉。只留下一個(gè)
哈希表:是一個(gè)元素為鏈表的數(shù)組,
LinkedHashSet:底層數(shù)據(jù)結(jié)構(gòu)由哈希表和鏈表組成。 哈希表保證元素的唯一性。 鏈表保證元素有素。(存儲(chǔ)和取出是一致)
TreeSet:能夠?qū)υ匕凑漳撤N規(guī)則進(jìn)行排序。 排序有兩種方式 A:自然排序 B:比較器排序 TreeSet集合的特點(diǎn):排序和唯一 通過觀察TreeSet的add()方法,我們知道最終要看TreeMap的put()方法。
A:自然排序(元素具備比較性) 讓元素所屬的類實(shí)現(xiàn)自然排序接口 Comparable B:比較器排序(集合具備比較性) 讓集合的構(gòu)造方法接收一個(gè)比較器接口的子類對象 Comparator
自然排序
package cn.itcast_05;
import java.util.TreeSet;
public class TreeSetDemo2 {
public static void main(String[] args) {
// 創(chuàng)建集合對象
TreeSet ts = new TreeSet();
// 創(chuàng)建元素
Student s1 = new Student("linqingxia", 27);
Student s2 = new Student("zhangguorong", 29);
Student s3 = new Student("wanglihong", 23);
Student s4 = new Student("linqingxia", 27);
Student s5 = new Student("liushishi", 22);
Student s6 = new Student("wuqilong", 40);
Student s7 = new Student("fengqingy", 22);
// 添加元素
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6);
ts.add(s7);
// 遍歷
for (Student s : ts) {
System.out.println(s.getName() + "---" + s.getAge());
}
}
}
/*學(xué)生類*/
package cn.itcast_05;
/*
* 如果一個(gè)類的元素要想能夠進(jìn)行自然排序,就必須實(shí)現(xiàn)自然排序接口
*/
public class Student implements Comparable {
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
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 int compareTo(Student s) {
// return 0;
// return 1;
// return -1;
// 這里返回什么,其實(shí)應(yīng)該根據(jù)我的排序規(guī)則來做
// 按照年齡排序,主要條件
int num = this.age - s.age;
// 次要條件
// 年齡相同的時(shí)候,還得去看姓名是否也相同
// 如果年齡和姓名都相同,才是同一個(gè)元素
int num2 = num == 0 ? this.name.compareTo(s.name) : num;
return num2;
}
}
---------------------
作者:小峰峰瘋瘋的
來源:CSDN
原文:https://blog.csdn.net/gafeng123456/article/details/50772296
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!
比較器排序
package cn.itcast_07;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
// 創(chuàng)建集合對象
// TreeSet ts = new TreeSet(); //自然排序
// public TreeSet(Comparator comparator) //比較器排序
// TreeSet ts = new TreeSet(new MyComparator());
// 如果一個(gè)方法的參數(shù)是接口,那么真正要的是接口的實(shí)現(xiàn)類的對象
// 而匿名內(nèi)部類就可以實(shí)現(xiàn)這個(gè)東西
TreeSet ts = new TreeSet(new Comparator() {
@Override
public int compare(Student s1, Student s2) {
// 姓名長度
int num = s1.getName().length() - s2.getName().length();
// 姓名內(nèi)容
int num2 = num == 0 ? s1.getName().compareTo(s2.getName())
: num;
// 年齡
int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
return num3;
}
});
// 創(chuàng)建元素
Student s1 = new Student("linqingxia", 27);
Student s2 = new Student("zhangguorong", 29);
Student s3 = new Student("wanglihong", 23);
Student s4 = new Student("linqingxia", 27);
Student s5 = new Student("liushishi", 22);
Student s6 = new Student("wuqilong", 40);
Student s7 = new Student("fengqingy", 22);
Student s8 = new Student("linqingxia", 29);
// 添加元素
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6);
ts.add(s7);
ts.add(s8);
// 遍歷
for (Student s : ts) {
System.out.println(s.getName() + "---" + s.getAge());
}
}
}
Map:鍵值對、鍵唯一、值不唯一。Map 集合中存儲(chǔ)的是鍵值對,鍵不能重復(fù),值可以重復(fù)。根據(jù)鍵得到值,對 map 集合遍歷時(shí)先得到鍵的 set 集合,對 set 集合進(jìn)行遍歷,得到相應(yīng)的值。
Map集合常用的子類有兩種: HashMap ?TreeMap
1.HashMap集合
注意:
Map集合都是針對鍵有效,且鍵是唯一的,?如果有相同的鍵,則第二個(gè)鍵的值覆蓋掉第一個(gè)鍵的值,如果第一次給HashMap添加元素,則put()方法返回值為null,第二次添加相同鍵的元素,則返回第一次添加的元素的值
存儲(chǔ)自定義對象的兩種方式:
自定義對象為鍵 ?:不能重復(fù) ,需要重寫equals()和HashCode()兩個(gè)方法
自定義對象為值 ?:可以重復(fù)
注釋:
如果成員變量的值相同則認(rèn)為是同一個(gè)人,即重復(fù)
HashMap底層依賴的是哈希表
哈希表依賴于兩個(gè)方法:equals()和HashCode();
//自定義對象作為鍵,必須具有唯一性,輸出不能保證順序
面試題:
HashMap和HashTable的區(qū)別?
共同點(diǎn):都是基于Map集合的實(shí)現(xiàn)類,都是哈希表的實(shí)現(xiàn)類
HashMap集合:線程不安全,執(zhí)行效率高,不同步,允許null值和null鍵
HashTable集合:線程安全,執(zhí)行效率低,同步,不允許null值和null鍵
線程安全的類:
StringBuffer ? ?:字符串緩沖區(qū)
Vector ? ? ? ? ? ? :List集合的子集合
HashTable ? ? ? :Map集合的子集合
2.LinkedHashMap集合
LinkedHashMap集合是Map接口基于哈希表和鏈表實(shí)現(xiàn)的
哈希表可保證鍵的唯一性
鏈表保證了元素的有序性(存儲(chǔ)和取出一致)
3.TreeMap集合
TreeMap集合的兩種排序方式:
自然排序:自定義的類實(shí)現(xiàn)Comparable接口,通過無參構(gòu)造形式創(chuàng)建對象,并且重寫ComparaTo()方法
比較器排序:通過public TreeSet(Comparator comparator)構(gòu)造方法創(chuàng)建對象,并且重寫了Compare()方法
比較器排序的兩種方式:
1).創(chuàng)建實(shí)現(xiàn)類繼承Comparator接口,并且重寫Compare()方法
2).直接使用匿名內(nèi)部類實(shí)現(xiàn),重寫Compare()方法,不用創(chuàng)建實(shí)現(xiàn)類
TreeSet集合保證元素是看ComparaTo()方法或者Compare()方法返回值是否為0;
TreeSet集合底層依賴于TreeMap集合的方法,存儲(chǔ)方式為紅黑樹結(jié)構(gòu)
4.Collections工具類
Collections和Collection的區(qū)別:
Collection:頂層次單列集合的根接口,它是一個(gè)集合,也是一個(gè)接口
Collections:是針對集合操作的工具類,里面包含了一些功能,隨機(jī)置換,集合里面的二分
查找,將集合的元素進(jìn)行反轉(zhuǎn)
Collections集合的常用方法:
public static int binarySearch(List list,T key) ? 二分查找
public static ?T max(Collection coll): 獲取集合中的最大值
public static void reverse(List> list) :將集合中的元素順序反轉(zhuǎn)
public static void shuffle(List> list) :將集合中的元素打亂
public static void sort(List<> list) :將集合中的元素進(jìn)行排序
總結(jié)
以上是生活随笔為你收集整理的java 集合数据类型_Java基础知识(数据类型和集合)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java简单框架测试-(添加注解)
- 下一篇: 反物质”世界存在吗