集合框架
1、集合又称为容器,用于存储、提取、删除数据;JDK提供的集合API都包含在 java.util 包内。
2、集合框架两大分支:Collection接口和Map接口
Collection集合:
Map集合:
List接口
概述:
1、List接口继承Collection接口;
2、该接口属于数据结构中的线性结构,用户可以根据元素的整数索引来访问元素;
List接口实现类:
- ArrayList(数组线性表)
(a) List 接口的实现类。其内部基于一个大小可变数组来存储
(b) 允许存储 null 元素 - LinkedList(双向链表)
(a) List 接口的链接列表实现类
(b) 允许存储 null 元素 - Vector(向量)
(a) 功能和ArrayList一样
(b) 线程安全 - Stack(栈)
(a) 表示后进先出(LIFO)的对象堆栈
List接口常用方法:
- add(Object element) 向列表的尾部添加指定的元素
- size() 返回列表中的元素个数
- get(int index) 返回列表中指定位置的元素,index从0开始
- add(int index, Object element) 在列表的指定位置插入指定元素
- set(int i, Object element) 将索引i位置元素替换为元素element并返回被替换的元素。
- clear() 从列表中移除所有元素
- isEmpty() 判断列表是否包含元素,不包含元素则返回 true,否则返回false
- iterator() 返回按适当顺序在列表的元素上进行迭代的迭代器
- contains(Object o) 如果列表包含指定的元素,则返回 true。
- remove(int index) 移除列表中指定位置的元素,并返回被删元素
- remove(Object o) 移除集合中第一次出现的指定元素,移除成功返回true,否则返回false。
下面以ArrayList为例通过代码演示List接口的方法:
(ArrayList和LinkedList,由于这两个类都是List接口的实现类,所以他们中定义的方法大多是一样的)
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;//引包
public class Test1 {
//集合:是一个存储或获取数据的容器
//List Set Map
public static void main(String[] args) {
//List
ArrayList<String> names = new ArrayList<String>();
//<String>为泛型,用于限制集合中所能保存的数据类型,等效于数组中的元素类型
names.add("Jim");//向集合中添加数据
names.add("Jack");
names.add("Make");
int size = names.size();//获取集合中有多少个元素
System.out.println(size);
boolean flag = names.isEmpty();//用于判断集合中是否含有元素,没有元素则返回true,否则返回false
System.out.println(flag);
//names.clear(); //用于清空集合中的元素
flag = names.isEmpty();
System.out.println(flag);
String name = names.get(0);//List可以通过get方法获取元素,和数组一样是从0开始的
System.out.println(name);
//for循环遍历集合
for(int i=0;i<names.size();i++) {
String n = names.get(i);
System.out.println(n);
}
for(String str:names) {
System.out.println(str);
}
List<String> list = new ArrayList<String>();//多态
list.add("Jimmy");
list.add("Kate");
list.add(1, "Make");//向特定位置插入数据,此位置后的数据会自动后移 "Jimmy" "Make" "Kate"
for(String str:list) {
System.out.println(str);
}
list.set(1, "Jack");//将指定位置的元素替换为新元素 "Jimmy" "Jack" "Kate"
for(String str:list) {
System.out.println(str);
}
//遍历器遍历集合
Iterator<String> iterator = list.iterator();//返回按适当顺序在列表的元素上进行迭代的迭代器,可以理解为一个指针
while(iterator.hasNext()) {//判断下一个位置是否有元素
System.out.println(iterator.next());//指向下一个位置并把元素取出
}
}
}
LinkedList中除了有上述ArrayList的方法,还有如下新增的方法:
- void addFirst(Object o) 将指定数据元素插入此集合的开头,原来元素(如果有)后移
- void addLast(Object o) 将指定数据元素插入此集合的结尾
- Object getFirst() 返回此集合的第一个数据元素
- Object getLast() 返回此集合的最后一个数据元素
- Object removeFirst() 移除并返回集合表的第一个数据元素
- Object removeLast() 移除并返回集合表的最后一个数据元素
ArrayList线性表与数组的区别:
- 两者本质的区别在与长度是否可变:数组是定长有序的线性集合;线性表是任意长度的线性集合;
- 两者添加元素的方式不同:数组使用下标:array [index];数组线性表使用add方法:list.add(value);
- 两者获取元素的方式不同:数组使用下标:array [index];数组线性表使用get方法:list.get(index);
- 获取长度的方式不同:数组使用length属性;数组线性表使用size()方法。
ArrayList和LinkedList区别:
- ArrayList是基于动态数组存储的数组线性表数据结构,使用连续的内存单元存储数据元素,对元素的遍历速度较快,LinkedList在遍历集合元素方面比较慢,因为在遍历过程中需要找寻下个元素的地址。
- LinkedList是使用指针关联的双向链表数据结构,前一个元素都记录了后一个元素的地址,后一个元素也记录了前一个元素的地址,当添加或删除数据元素时,LinkedList比较快,因为ArrayList需要移动其被添加(或删除)元素后面(最后一个除外)的全部元素。
Set接口
概述:
Set接口继承Collection接口
Set接口常用实现类:
-
HashSet
(a) 实现了 Set 接口
(b) “它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变”
(c)允许使用 null 元素 -
LinkedHashSet
(a) HashSet的子类
(b) 由于该实现类对象维护着一个运行于所有元素的双重链接列表,由于该链接列表定义了迭代顺序,所以在遍历该实现类集合时按照元素的插入顺序进行遍历 -
TreeSet
(a) 既实现Set接口,同时也实现了SortedSet接口,具有排序功能
(b) 存入TreeSet中的对象元素需要实现Comparable接口
Set接口常用方法:
- add(Object obj):向Set集合中添加元素,添加成功返回true,否则返回false
- size() :返回Set集合中的元素个数
- remove(Object obj) : 删除Set集合中的元素,删除成功返回true,否则返回false。
- isEmpty() :如果Set不包含元素,则返回 true ,否则返回false
- clear() : 移除此Set中的所有元素
- iterator() :返回在此Set中的元素上进行迭代的迭代器
- contains(Object o):如果Set包含指定的元素,则返回 true,否则返回false
下面以HashSet实现类为例通过代码演示Set接口方法:
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;//引包
public class Test2 {
public static void main(String[] args) {
//Set
Set<String> names = new HashSet<String>();//调用HashSet构造方法,源码:
//public HashSet() {
// map = new HashMap<>();//为map成员变量赋值,HashMap对象
//}
names.add("Jim");//源码:
//public boolean add(E e) {
// return map.put(e, PRESENT)==null;
//}
//向Map集合中HashMap容器添加数据 PRESENT常量
//本质:HashSet存储数据时本质是存到了HashMap集合的key
boolean flag = names.isEmpty();//判断是否为空
System.out.println(flag);
//names.clear();//清空HashSet中所有元素
flag = names.isEmpty();
System.out.println(flag);
//names.get(0);get方法不存在
names.add("Jack");
//遍历:不能用传统for循环进行遍历
for(String str:names) {
System.out.println(str);
}
//用迭代器遍历
Iterator<String> iterator = names.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
注:Set与List集合的区别:
- List集合可以保存重复数据,但Set集合不可以
- List集合按照存储数据顺序保存的,Set集合中HashSet不是按照存储的顺序保存的,具有不确定性;
LinkedHashSet是按用户存储的顺序保存数据的;TreeSet按照自然顺序保存
Map接口
概述:
- Map集合基于 键(key)/值(value)映射。每个键最多只能映射一个值。键可以是任何引用数据类型的值,不可重复;值可以是任何引用数据类型的值,可以重复;键值对存放是无序的。
Map常用实现类:
- HashMap:允许使用 null 值和 null 键;此类不保证映射的顺序;在多线程操作下不安全
- LinkedHashMap:基于哈希表和链接列表的实现类;具有可预知的迭代顺序(双重链接表的有序性)
- Properties:Hashtable的一个子类;属性列表中每个键及其对应值都是一个字符串;在多线程操作下安全
常用方法:
- put(K key, V value) 将键(key)/值(value)映射存放到Map集合中
- get(Object key) 返回指定键所映射的值,没有该key对应的值则返回 null
- size() 返回Map集合中数据数量
- clear() 清空Map集合
- isEmpty () 判断Map集合中是否有数据,如果没有则返回true,否则返回false
- remove(Object key) 删除Map集合中键为key的数据并返回其所对应value值。
- values() 返回Map集合中所有value组成的以Collection数据类型格式数据。
- containsKey(Object key) 判断集合中是否包含指定键,包含返回 true,否则返回false
- containsValue(Object value) 判断集合中是否包含指定值,包含返回 true,否则返回false
- keySet() 返回Map集合中所有key组成的Set集合
- entrySet() 将Map集合每个key-value转换为一个Entry对象并返回由所有的Entry对象组成的Set集合
下面以HashMap实现类为例通过代码演示Map接口方法:
import java.util.HashMap;
import java.util.Map;
public class Test3 {
public static void main(String[] args) {
//Map
Map<String,Integer> scores = new HashMap<String,Integer>();//<String,Integer>,其中String用于限定key的数据类型,Integer显示value的数据类型,泛型不能使基本数据类型
scores.put("Jim", 100);//添加数据
scores.put("Jim", 60);//Map集合key不允许重复,重复的话后写的会覆盖前写的
scores.put("Jack", 90);
int score = scores.get("Jim");//获取Jim成绩
System.out.println(score);
int size = scores.size();//获得集合元素个数
System.out.println(size);
scores.clear();//清空集合
size = scores.size();
System.out.println(size);
boolean flag = scores.isEmpty();//判断是否为空
System.out.println(flag);
scores.put("Jim", 100);
scores.replace("Jim", 0);//替换,把Jim的value用0替换掉原来的100
score = scores.get("Jim");
System.out.println(score);
}
}
HashMap集合的遍历方式:
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class Test3 {
public static void main(String[] args) {
//Map
Map<String,Integer> scores = new HashMap<String,Integer>();
scores.put("Jim", 100);
scores.put("Kate", 90);
//第一种
Set<String> names = scores.keySet();//获取集合中所有key-value的key值组成的Set集合 "Jim" "Kate"
//加强循环
for (String key : names) {
int value = scores.get(key);
System.out.println(value);
}
//迭代器
Iterator<String> iterator = names.iterator();
while(iterator.hasNext()) {
String key = iterator.next();
int value = scores.get(key);
System.out.println(value);
}
//第二种
Set<Entry<String, Integer>> entries = scores.entrySet();//将HashMap集合中key-value用Entry对象包含
//加强循环
for (Entry<String, Integer> entry : entries) {
String key = entry.getKey();
int value = entry.getValue();
System.out.println(value);
}
//迭代器
Iterator<Entry<String, Integer>> it = entries.iterator();
while(it.hasNext()) {
Entry<String, Integer> entry = it.next();
String key = entry.getKey();
int value = entry.getValue();
System.out.println(value);
}
}
}