一、Collection和Map的簡單結構圖
二、容器的介紹與比較
1、Collection容器:一組各自獨立的元素集合
(1)List、Set對比
List:有序可重複的元素集合
Set:無序不可重複的元素集合,底層實現爲Map
(2)ArrayList、LinkedList、Vector對比
ArrayList、LinkedList、Vector均爲List接口的實現類
ArrayList:底層實現爲數組,線程不安全,查詢效率高,插入刪除效率低
LinkedList:底層實現爲鏈表,線程不安全,查詢效率低,插入刪除效率高
Vector:底層實現爲數組,線程安全
(3)Set與HashSet使用方法區別
Set是接口,HashSet是Set的一個實現子類。
Set變量實現時發生多態,需要指向具體的實現類對象,可以是HashSet類對象、也可以是其他子類對象,HashSet變量實現時創建的是HashSet類對象
定義Set變量,實例化時創建需要的子類對象,後續如果需要修改存儲的類型,直接修改實例化時創建的對象就可以,修改方便
2、Map容器:以key-value(鍵值對)形式存儲數據,key允許重複,底層實現形式:數組+鏈表
(1)HashMap、HashTable對比
HashMap:基於哈希表;線程不安全;沒有contains()方法;key值不重複,key和value值允許出現null值;重新計算hashCode
HashTable:基於哈希表;線程安全;有contains()方法;key值不重複,key和value都不允許出現null值;直接使用對象的hashCode
(2)Map與HashMap使用方法區別
Map是接口,HashMap是Map的一個實現子類。
Map變量實現時發生多態,需要指向具體的實現類對象,可以是HashMap類對象、也可以是其他子類對象,HashMap變量實現時創建的是HashMap類對象
定義Map變量,實例化時創建需要的子類對象,後續如果需要修改存儲的類型,直接修改實例化時創建的對象就可以,修改方便
三、容器的使用
1、容器的方法調用
(1)Map接口類方法使用
import java.util.HashMap;
import java.util.Map;
/**
* Map接口類的方法使用
* put、get、remove、putAll、constaintKey、constaintValue、clear、size、isEmpty
*
*/
public class MapTest {
public static void main(String[] args) {
Map map = new HashMap();
//put(key,value):向容器中添加鍵值對,key值不可以重複,若key重複,後面新添加的value會覆蓋前面的value
map.put("姓名", "張三");
map.put("部門", "信息部");
map.put("姓名", "李四");
map.put("單位", "信息部");
//get(key):根據key從元素中獲取value,返會value對象
String name = (String) map.get("姓名");
System.out.println(name);
//size():返回容器中鍵值對的個數
int size = map.size();
System.out.println(size);
//containsKey(key):判斷容器中是否包含與參數key相等的key,返回boolean,底層比較實用equals
boolean b1 = map.containsKey("姓名");
System.out.println(b1);
//containsValue(value):判斷容器中是否包含與參數value相等的value,返回boolean,底層比較實用equals
boolean b2 = map.containsValue("信息部");
System.out.println(b2);
//remove(key):刪除容器中key等於參數key的鍵值對
map.remove("單位");
//isEmpty():判斷容器中是否有元素,若存在元素,則返回false,若不存在元素,返回true
boolean b3 = map.isEmpty();
System.out.println(b3);
//putAll(Map m):將參數容器m中的所有元素添加到當前容器中
Map m = new HashMap();
m.put("薪資", 3000);
m.put("年齡", 20);
map.putAll(m);
System.out.println(map.get("年齡"));
//clear():清空容器中所有元素
map.clear();
System.out.println(map.size());
}
}
(2)Set接口類方法使用
import java.util.HashSet;
import java.util.Set;
/**
* Set接口類方式使用
* add,addAll,size,contains,containsAll,isEmpty,remove,removaAll,clear
*
*/
public class SetTest {
public static void main(String[] args) {
Set set = new HashSet();
//add(e):向Set集合中添加元素,添加元素不可重複
set.add("aaa");
set.add("bbb");
//addAll(Collection c):將參數集合c中的所有元素添加到當前集合set中
Set set1 = new HashSet();
set1.add("ccc");
set.addAll(set1);
//size():返回集合中的元素個數
System.out.println(set.size());
//contains(e):判斷Set集合中是否包含e對象,若包含返回true,否則返回false
boolean b = set.contains("aaa");
System.out.println(b);
//containsAll(Collect c):判斷集合Set中是否包含參數set集合,若包含返回true,否則返回false
boolean b1 = set.containsAll(set1);
System.out.println(b1);
//isEmpty():判斷集合中是否有元素,若存在元素,則返回false,若不存在元素,返回true
boolean b2 = set.isEmpty();
System.out.println(b2);
//remove(e):將元素e從結合中移除
set.remove("aaa");
//removeAll(Collect c):將當前集合中所有包含在集合c中的元素全部移除
set.removeAll(set1);
//clear():清空集合中的所有元素
set.clear();
System.out.println(set.size());
}
}
(3)List接口方法使用
```java
import java.util.ArrayList;
import java.util.List;
/**
* List接口方法使用
* add、addAll、size、get、set、remove、clear、isEmpty、contains
*
*/
public class ListTest {
public static void main(String[] args) {
List list = new ArrayList();
//add(e):向List容器末尾添加元素
list.add("aaa");
list.add("bbb");
//add(index, element):向List容器中index索引位置插入元素
list.add(1, "ccc");
//addAll(c):在List容器末尾添加參數容器c中所有元素
List list1 = new ArrayList();
list1.add("測試addAll");
list.addAll(list1);
//addAll(index, c):在List容器index索引位置插入參數容器c中所有元素
list.addAll(0, list1);
//size():返回集合中的元素個數
int size = list.size();
System.out.println(size);
//get(index):查找索引index位置的元素並返回
String str = (String) list.get(2);
System.out.println(str);
//set(index, element):將容器中index位置的元素修改爲element
list.set(0, "修改數據");
System.out.println(list.get(0));
//remove(index):從容器中移除索引位置index的元素
list.remove(1);
System.out.println(list.get(1));
//remove(o):從容器中移除元素o
list.remove("aaa");
//clear():清空容器中所有元素
list.clear();
//contains(o):判斷容器中是否包含元素o,若包含返回ture,否則返回false
boolean b1 = list.contains("ccc");
System.out.println(b1);
//constainsAll(c):判斷容器中是否包含參數容器中的所有元素,若包含返回ture,否則返回false
boolean b2 = list.containsAll(list1);
System.out.println(b2);
//isEmpty():判斷容器中是否有元素,若存在元素返回false,否則返回true
boolean b3 = list.isEmpty();
System.out.println(b3);
}
}
2、自定義實現ArrayList類、LinkedList類(加深理解)
(1)自定義實現ArrayList類中主要方法
```java
package cn.cjy.collection;
import java.lang.reflect.Array;
/**
* 自定義實現ArrayList
*/
public class MyArrayList {
private Object[] elementData;
private int size;
public int size(){ //獲取容器元素個數
return size;
}
public boolean isEmpty(){ //判斷容器中爲空
return size==0;
}
public MyArrayList(){
this(3);
}
public MyArrayList(int initialCapacity){
if(initialCapacity<0){
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
elementData = new Object[initialCapacity];
}
//向容器中添加元素
public void add(Object obj){
ensureCapacity();//數組擴容
elementData[size++] = obj;
}
//向容器中指定位置插入元素
public void add(int index,Object obj){
rangeCheck(index);
ensureCapacity();
System.arraycopy(elementData, index, elementData, index+1, size-index);
elementData[index] = obj;
size++;
}
//修改容器中指定位置元素
public void set(int index,Object obj){
rangeCheck(index);
elementData[index] = obj;
}
//移除容易中指定位置元素
public void remove(int index){
rangeCheck(index);
int noveNum = size-index-1;
if(noveNum>0){
System.arraycopy(elementData, index+1, elementData, index, noveNum);
}
elementData[size--]=null;
}
//移除容器中的等於obj的元素
public void remove(Object obj){
for(int i=0;i<size;i++){
if(get(i).equals(obj)){
remove(i);
}
}
}
//獲取容器中指定位置元素
public Object get(int index){
rangeCheck(index);
return elementData[index];
}
//檢查索引是否合法
private void rangeCheck(int index){
if(index<0 || index>=size){
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
}
//數組擴容
private void ensureCapacity(){
if(size == elementData.length){
Object[] newArray = new Object[size*2+1];
System.arraycopy(elementData, 0, newArray, 0, elementData.length);
elementData = newArray;
}
}
public static void main(String[] args) {
MyArrayList list = new MyArrayList();
list.add("測試");
list.add("測試2");
list.add("測試3");
list.add("測試4");
list.add(2,"我是中途加進來的");
list.remove(0);
list.set(2, "我是修改");
list.remove("測試4");
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
(2)自定義實現LinkedList類中主要方法
package cn.cjy.collection;
/**
* 自定義雙向鏈表集合 LinkedList
*/
public class MyLinkedList {
private MyNode first;
private MyNode last;
private int size;
public int size(){ //返回容器中元素個數
return size;
}
public MyLinkedList(){
}
//獲取指定位置元素
public Object get(int index){
rangeCheck(index);
MyNode temp = node(index);
if(temp != null){
return temp.getNode();
}
return null;
}
public MyNode node(int index){ //根據索引遍歷找對象
MyNode temp=null;
if(first != null){
if(index < (size>>1)){ //如果index小於size的一半,從前往後找,否則從後往前找
temp = first;
for(int i=0;i<index;i++){
temp = temp.getNext();
}
}else{
temp = last;
for(int i=size-1; i>index; i--){
temp = temp.getPrevious();
}
}
}
return temp;
}
//向容器中添加元素
public void add(Object obj){
MyNode myNode = new MyNode();
if(first == null){
myNode.setNode(obj);
first = myNode;
last = myNode;
}else{
myNode.setPrevious(last);
myNode.setNode(obj);
last.setNext(myNode);
last = myNode;
}
size++;
}
//向容器中指定位置插入元素
public void add(int index,Object obj){
rangeCheck(index);
MyNode temp = node(index); //找到節點
MyNode myNode = new MyNode();//創建新節點
if(temp !=null){
myNode.setPrevious(temp.getPrevious());
myNode.setNode(obj);
myNode.setNext(temp);
temp.getPrevious().setNext(myNode);//原index節點的上節點的下節點改爲新節點
temp.setPrevious(myNode); //原index節點的上節點設爲新節點
size++;
}
}
//修改容器中指定位置元素
public void set(int index,Object obj){
rangeCheck(index);
MyNode temp = node(index); //找到節點
if(temp != null){
temp.setNode(obj);
}
}
//移指定位置元素
public void remove(int index){
rangeCheck(index);
MyNode temp = node(index); //找到節點
if(temp != null){
if(first == temp){
if(first.getNext() != null){
first.getNext().setPrevious(null);
first = first.getNext();
}else{
first = null;
last = null;
}
}else if(last == temp){
if(last.getPrevious() != null){
last.getPrevious().setPrevious(null);
last = last.getPrevious();
}else{
first = null;
last = null;
}
}else{
temp.getPrevious().setNext(temp.getNext());
temp.getNext().setPrevious(temp.getPrevious());
}
size--;
}
}
public void rangeCheck(int index){ //檢查索引是否合法
if(index<0 || index >= size){
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyLinkedList list = new MyLinkedList();
list.add("鏈表測試");
list.add("111");
list.add("222");
list.add(1,"test");
list.set(1,"test002");
System.out.println(list.get(1));
list.remove(1);
System.out.println(list.get(1));
//list.remove("鏈表測試");
//System.out.println(list.get(0));
}
}
3、迭代器遍歷容器中的元素
(1)Set集合的遍歷方式
package cn.cjy.collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* 迭代器遍歷Set
*/
public class IteratorSet {
public static void main(String[] args) {
Set set = new HashSet();
set.add("語文");
set.add("數學");
set.add("英語");
//while循環遍歷
Iterator itera = set.iterator();
while(itera.hasNext()){
String str = (String) itera.next();
System.out.println(str);
}
//for循環遍歷
for(Iterator itera1 = set.iterator();itera1.hasNext();){
String str1 = (String) itera1.next();
System.out.println(str1);
}
}
}
(2)Map的2種遍歷方式
package cn.cjy.collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* 迭代器遍歷Map
*
*/
public class IteratorMap {
public static void main(String[] args) {
Map map = new HashMap();
map.put("姓名", "張三");
map.put("性別", "男");
map.put("部門", "信息部");
//遍歷Map的第一種方式
Set<Entry> set1 = map.entrySet(); //將Map轉換成存放鍵值對的Set集合
Iterator itera1 = set1.iterator();
while(itera1.hasNext()){
Entry entry = (Entry) itera1.next();
String str1 = (String) entry.getKey();
String str2 = (String) entry.getValue();
System.out.println(str1+":"+str2);
}
//遍歷Map的第二種方式
Set set2 = map.keySet(); //將Map的鍵放入Set集合
Iterator itera2 = set2.iterator();
while(itera2.hasNext()){
String str1 = (String) itera2.next(); //獲取鍵
String str2 = (String) map.get(str1); //獲取值
System.out.println(str1+":"+str2);
}
}
}
(3)List的遍歷方式
package cn.cjy.collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* List的遍歷方式
*/
public class IteratorList {
public static void main(String[] args) {
List list = new ArrayList();
list.add("語文");
list.add("數學");
list.add("英語");
//根據索引循環遍歷
for(int i=0;i<list.size();i++){
String str = (String) list.get(i);
System.out.println(str);
}
//根據迭代器循環遍歷
Iterator itera = list.iterator();
while(itera.hasNext()){
String str1 = (String) itera.next();
System.out.println(str1);
}
}
}
4、容器裝載數據應用舉例
(1)List
package cn.cjy.collection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* List<Map>存儲數據
*/
public class MapStore {
public static void main(String[] args) {
List<Map> list = new ArrayList<Map>();
Map map1 = new HashMap();
map1.put("姓名", "張三");
map1.put("年齡", 20);
map1.put("入職日期", "2019-01-01");
Map map2 = new HashMap();
map2.put("姓名", "李四");
map2.put("年齡", 21);
map2.put("入職日期", "2018-01-01");
Map map3 = new HashMap();
map3.put("姓名", "王二");
map3.put("年齡", 22);
map3.put("入職日期", "2017-01-01");
list.add(map1);
list.add(map2);
list.add(map3);
for(Map m : list){
String name = (String) m.get("姓名");
int age = (Integer) m.get("年齡");
String inDate = (String) m.get("入職日期");
System.out.println(name+" "+age+" "+inDate);
}
}
}
(2)ArrayList存儲數據
自定義一個實體類:Employee 列:姓名、年齡、入職日期。然後裝載到 ArrayList容器中,最後增強for循環輸出姓名
package cn.cjy.collection;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Employee {
private String name; //姓名
private int age; //年齡
private Date inDate; //入職日期
public Employee(){
}
public Employee(String name, int age, String inDate) {
super();
this.name = name;
this.age = age;
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
this.inDate = format.parse(inDate);
} catch (ParseException e) {
e.printStackTrace();
}
}
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;
}
public Date getInDate() {
return inDate;
}
public void setInDate(Date inDate) {
this.inDate = inDate;
}
}
package cn.cjy.collection;
import java.util.ArrayList;
import java.util.List;
/**
* ArrayList存儲數據
*/
public class ArrayListStore {
public static void main(String[] args) {
Employee e1 = new Employee("張三", 20, "2019-01-01");
Employee e2 = new Employee("李四", 21, "2018-01-01");
Employee e3 = new Employee("王二", 22, "2017-01-01");
List<Employee> list = new ArrayList<Employee>();
list.add(e1);
list.add(e2);
list.add(e3);
for(Employee e : list){
System.out.println(e.getName());
}
}
}
四、補充
1、ArrayList中size與length的區別
size是ArrayList中元素的個數,length是數組長度,size<=length
2、System.arraycopy() 函數:複製數組
package cn.cjy.collection;
/**
* 使用System.arraycopy()函數複製數組
* System.arraycopy(src, srcPos, dest, destPos, length)
* src:源數組
* srcPos:源數組開始複製位置
* dest:目標數組
* destPos:目標數組開始放的位置
* length:複製的長度
*/
public class ArrayCopyTest {
public static void main(String[] args) {
String[] arr1 = new String[5];
arr1[0] = "測試數組複製";
String[] arr2 = new String[]{"aaa","bbb","ccc"};
System.arraycopy(arr2, 1, arr1, 1, 2);
for(int i=0;i<arr1.length;i++){
System.out.println(arr1[i]);
}
}
}
``