Java集合
集合的概念
概念
对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能。
和数组的区别
- 数组长度固定,集合长度不固定
- 数组可以存储基本类型和引用类型,集合只能存储引用类型
Collection接口

Collection:该体系的跟接口,代表一组对象,称为“集合”。
List接口的特点:有序、有下标、元素可重复
Set接口的特点:无序、无下标、元素不能重复
常用方法
| 返回值类型 | 方法 | 说明 |
|---|---|---|
| boolean | add(Object obj) | 添加一一个对象 |
| boolean | addAll (Collection c) | 将一个集合中的所有对象添加到此集合中 |
| void | clear() | 清空此集合中的所有对象 |
| boolean | contains (Object o) | 检查此集合中是否包含o对象 |
| boolean | equals (Object o) | 比较此集合是否与指定对象相等 |
| boolean | isEmpty() | 判断此集合是否为空 |
| boolean | remove (Object o) | 在此集合中移除o对象 |
| int | size() | 返回此集合中的元素个数 |
| Object[] | toArray() | 将此集合转换成数组 |
Collection接口的使用
public class CollectionTest {
/**
* Collection接口的使用
* 1、添加元素
* 2、删除元素
* 3、遍历元素
* 4、判断
*/
public static void main(String[] args) {
//创建集合
Collection collection = new ArrayList();
//添加元素
collection.add("老虎");
collection.add("狮子");
collection.add("大象");
//删除元素
// collection.remove("狮子");
// collection.clear();
// System.out.println(collection);
//遍历元素 两种方式
//方法1:使用增强for
for (Object o : collection) {
System.out.println(o);
}
//方法2:使用迭代器(专门用来遍历数组的一种方式)
//hasNext() 判断有没有下一个元素
//next() 获取下一个元素
//remove() 去删除当前元素
Iterator iterator = collection.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
iterator.remove();
}
System.out.println(collection);
//判断
System.out.println(collection.contains("狮子"));
System.out.println(collection.isEmpty());
}
}
注意:使用迭代器遍历集合时,不能直接操作集合,你如果要对list进行增删操作,都必须经过Iterator,否则Iterator遍历时会乱,所以直接对list进行删除时,Iterator会抛出ConcurrentModificationException异常
List接口与实现类
List接口
常用方法
| 返回值类型 | 方法 | 说明 |
|---|---|---|
| void | add(int index, Object o) | 在index位置插入对象o |
| boolean | addAll(int index, Collection c) | 将一个集合中的元素添加到此集合中的index位置 |
| Object | get(int index) | 返回集合中指定位置的元素 |
| List | subList (int fromIndex, int toIndex) | 返回fromIndex和toIndex之间的集合元素(留头不留尾) |
List接口的使用
/**
* List集合的使用
* 特点: 1、有序 有下标 2、可以重复
*/
public class ListTest {
public static void main(String[] args) {
//创建集合
List list = new ArrayList<>();
//添加元素
list.add("小米");
list.add("苹果");
list.add(0, "华为");
//删除元素
// list.remove(1);
// list.remove("小米");
// list.clear();
//遍历List集合 四种方式
//方式1:使用for循环
System.out.println("------使用for循环遍历------");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//方式2:使用增强for
System.out.println("------使用增强for遍历------");
for (Object o : list) {
System.out.println(o);
}
//方式3:使用迭代器
System.out.println("------使用Iterator遍历------");
Iterator iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//方式4:使用列表迭代器(ListIterator与Iterator的区别:ListIterator可以向前或向后遍历,添加、删除、修改元素)
ListIterator listIterator = list.listIterator();
System.out.println("------使用ListIterator向后遍历------");
while(listIterator.hasNext()){
System.out.println(listIterator.nextIndex()+":"+listIterator.next());
}
System.out.println("------使用ListIterator向前遍历------");
while(listIterator.hasPrevious()){
System.out.println(listIterator.previousIndex()+":"+listIterator.previous());
}
//判断
System.out.println(list.contains("小米"));
System.out.println(list.isEmpty());
//获取位置
System.out.println(list.indexOf("小米"));
}
}
使用for循环和ListIterator遍历可以获取元素的下标,使用增强for和Iterator则不能。
List实现类
ArrayList
- 数组结构实现,查询快、增删慢;
- JDK1.2版本,运行效率快、线程不安全。
Vector
- 数组结构实现,查询快、增删慢;
- JDK1.0版本,运行效率慢,线程安全。
LinkedList
- 链表结构实现,增删快,查询慢。
ArrayList和LinkedList的区别

泛型
Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。
常见的形式有泛型类,泛型接口,泛型方法。
语法:<T,...> T称为类型占位符,表示一种引用类型
好处:提高代码重用性,防止类型转换异常,提高代码安全性
为什么泛型的类型不能是基本数据类型?
泛型的定义:在程序中我们将一个对象放入集合中,但是集合不会记住对象的类型,当我们再次使用对象的时候,对象变为object类型,而程序中还是原来的类型,我们必须要自己转换其类型,为了解决这个问题,则提出泛型。
泛型要求包容的是对象类型,而基本数据类型在Java中不属于对象。但是基本数据类型有其封装类,且为对象类型。
Set接口与实现类
set接口
特点:无序、无下标、不能重复
方法全部是继承自collection接口
set接口的使用
/**
* 测试set接口的使用
* 特点:1、无序、无下标 2、不能重复
*/
public class SetTest {
public static void main(String[] args) {
//创建集合
Set<String> set = new HashSet<>();
//添加数据
set.add("华为");
set.add("小米");
set.add("苹果");
// set.add("苹果");
System.out.println("数据个数:"+set.size());
System.out.println(set);
//删除数据
// set.remove("苹果");
// set.clear();
// System.out.println(set);
//遍历
//1.使用增强for
for (String s : set) {
System.out.println(s);
}
//2.使用迭代器
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//判断
set.contains("小米");
set.isEmpty();
}
}
set接口实现类
HashSet
- 基于HashCode计算元素存放位置
- 当存入元素的哈希码相同时,会调用equals进行确认,如果结果为true,则拒绝后者存入。
- 存储结构:哈希表(数组+链表+红黑树)
- 存储过程:①根据hashcode计算保存位置,如果此位置为空,则直接保存,如果不为空执行第二步。②在执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
TreeSet
- 基于排列顺序实现元素不重复。
- 实现了SortedSet接口,对集合元素自动排序。
- 元素对象的类型必须实现Comparable接口,指定排序规则。
- 通过CompareTo方法确定是否为重复元素。
- 存储结构:红黑树
- Comparator实现定制比较(比较器)
TreeSet练习
/**
* 使用TreeSet集合实现字符串按照长度进行排序
*/
public class TreeSetTest {
public static void main(String[] args) {
//创建TreeSet集合 并指定比较规则(使用匿名内部类实现 Comparator 接口)
TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int n1 = o1.length()-o2.length();//根据长度进行比较
int n2 = o1.compareTo(o2);//默认比较方式
return n1==0?n2:n1;//长度一致执行默认比较方式,长度不一致根据长度比较
}
});
//给集合添加元素
treeSet.add("hello");
treeSet.add("zt");
treeSet.add("Integer");
treeSet.add("boolean");
treeSet.add("zhangsan");
treeSet.add("beijing");
System.out.println(treeSet);
}
}
Map接口与实现类
Map接口

Map接口的特点:
- 用于存储任意键值对(Key-Value)
- 键:无序、无下标、不允许重复(唯一)
- 值:无序、无下标、允许重复
常用方法:
| 返回值类型 | 方法 | 说明 |
|---|---|---|
| void | put(K key,V value) | 将对象存入到集合中,关联键值,key重复则覆盖原值 |
| 0bject | get (Object key) | 根据键获取对应的值 |
| Set |
keySet() | 返回所有key |
| Collection |
values() | 返回包含所有值的Collection集合 |
| Set<Map.Entry<K,V>> | entrySet() | 键值匹配的Set集合 |
map接口的使用
/**
* Map接口的使用
* 特点:1、存放键值对 2、键不能重复,值可以重复 3、无序
*/
public class MapTest {
public static void main(String[] args) {
//1.创建Map集合
HashMap<String, String> map = new HashMap<>();
//2.添加元素
map.put("China", "中国");
map.put("American", "美国");
map.put("England", "英国");
map.put("Janpane", "日本");
//3.删除元素
map.remove("Janpane");
System.out.println(map);
//3.遍历map
//3.1使用keyset()
System.out.println("------使用keyset()遍历------");
// Set<String> keySet = map.keySet();
// System.out.println(keySet);
for (String key : map.keySet()) {
System.out.println(key + ":" + map.get(key));
}
//3.2使用entrySet()
System.out.println("------使用entrySet()遍历------");
Set<Map.Entry<String, String>> entries = map.entrySet();
// System.out.println(entries);
for (Map.Entry<String, String> entry : entries) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
//4.判断
System.out.println(map.containsKey("China"));
System.out.println(map.containsValue("日本"));
}
}
Map接口实现类
HashMap
JDK1. 2版本,线程不安全,运行效率快,允许用null作为key或是value。
数据结构:哈希表(数组+链表+红黑树)
红黑树是JDK1.8之后加入的
构造方法
HashMap()
构造一个空的 HashMap ,默认初始容量(16)和默认负载系数(0.75)。
负载系数(0.75):当容量超过75%开始进行扩容
总结
- HashMap刚创建时,table是null, 为了节省空间,当添加第一 个元素时,table容 量调整为16
- 当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为原来的2倍。目的是减少调整元素的个数
- jdk1.8当每个链表长度大于8,并且数组元素个数大于等于64时,会调整为红黑树,目的提高执行效率
- jdk1.8当链表长度小于6时,调整成链表
- jdk1.8以前,链表是头插入,jdk1 .8以后是尾插入
HashTable
JDK1. 0版本,线程安全,运行效率慢;不允许null作为key或是value。
Propertise
Hashtable的子类, 要求key和value都是String。通常用于配置文件的读取。
TreeMap
实现了SortedMap接口(是Map的子接口),可以对key自动排序。
元素对象的类型必须实现Comparable接口,或者创建集合的时候实现Comparable(比较器)接口,自定义比较方法,不然会报类型强制转换异常ClassCastException
Collections工具类
概念
集合工具类,定义了除了存取以外的集合常用方法。
常用方法
| 方法 | 说明 |
|---|---|
| public static void reverse(List<?> list) | 反转集合中元素的顺序 |
| public static void shuffle(List<?> list) | 随机重置集合元素的顺序 |
| public static void sort(List |
升序排序(元素类型必须实现Comparable接口) |
| sort(List |
根据指定的比较器引起的顺序对指定的列表进行排序 |
Collections工具类的使用
/**
* Collections工具类的使用
*/
public class CollectionsTest {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(66);
list.add(8);
list.add(20);
list.add(108);
list.add(72);
list.add(80);
//sort排序
System.out.println("排序之前"+list);
Collections.sort(list);
System.out.println("排序之后"+list);
//binarySearch二分查找
int i = Collections.binarySearch(list,5);
System.out.println(i);
//copy复制 注意两个集合的大小必须一致才能复制,所以需要先对list2进行赋值
List<Integer> list2 = new ArrayList<>();
for (int j = 0; j <list.size() ; j++) {
list2.add(0);
}
Collections.copy(list2,list);
System.out.println(list2);
//reverse反转
Collections.reverse(list);
System.out.println("反转之后:"+list);
//shuffle打乱
Collections.shuffle(list);
System.out.println("打乱之后:"+list);
//List转成数组
Integer[] array = list.toArray(new Integer[0]);
System.out.println(array.length);
System.out.println(Arrays.toString(array));
//数组转成集合 该集合是一个受限集合,不能添加和删除
String[] names = {"张三","李四","王五"};
List<String> strings = Arrays.asList(names);
System.out.println(strings);
//把基本数据类型数组转换为集合时,需要把基本数据类型转换为引用数据类型
int[] num ={100,200,300,400};
List<int[]> ints = Arrays.asList(num);
Integer[] num1 ={100,200,300,400};
List<Integer> integers = Arrays.asList(num1);
}
}
集合总结
集合的概念:
- 对象的容器,和数组类似,定义了对多个对象进行操作的常用方法。
List集合:
- 有序、有下标、元素可以重复。 (ArrayList、LinkedList、 Vector)
Set集合:
- 无序、无下标、元素不可重复。 (HashSet、 TreeSet)
Map集合:
- 存储一对数据,无序、无下标,键不可重复,值可重复。 (HashMap、 HashTable、 TreeMap)
Collect ions:
- 集合工具类,定义了除了存取以外的集合常用方法。
TreeMap与TreeSet的区别
TreeSet的部分源码
public TreeSet() // ①
{
// 以自然排序方式创建一个新的 TreeMap,
// 根据该 TreeSet 创建一个 TreeSet,
// 使用该 TreeMap 的 key 来保存 Set 集合的元素
this(new TreeMap<E,Object>());
}
public TreeSet(Comparator<? super E> comparator) // ②
{
// 以定制排序方式创建一个新的 TreeMap,
// 根据该 TreeSet 创建一个 TreeSet,
// 使用该 TreeMap 的 key 来保存 Set 集合的元素
this(new TreeMap<E,Object>(comparator));
}
从①和②两个构造方法中可以看出,TreeSet 底层实际使用的存储容器就是 TreeMap。
红黑树
红黑树是一种自平衡排序二叉树,树中每个节点的值,都大于或等于在它的左子树中的所有节点的值,并且小于或等于在它的右子树中的所有节点的值,这确保红黑树运行时可以快速地在树中查找和定位的所需节点。

浙公网安备 33010602011771号