java基础003-集合

集合简介

Java中的集合是一组类和接口,用于在内存中管理对象。集合可以帮助我们更有效地存储和操作数据。本教程将介绍Java集合框架的基础知识。

集合框架的层次结构

Java集合框架由多个类和接口组成,它们之间存在层次关系。最常见的集合框架如下:

  • Collection接口:是所有集合接口的根接口。
    – List接口:有序集合,允许重复元素。
    – ArrayList类:实现了List接口,使用数组实现。
    – LinkedList类:实现了List接口,使用链表实现。
  • Set接口:不允许重复元素。
    – HashSet类:实现了Set接口,使用哈希表实现。
    – TreeSet类:实现了Set接口,基于红黑树实现。
  • Map接口:键值对集合。
    – HashMap类:实现了Map接口,使用哈希表实现。
    – TreeMap类:实现了Map接口,基于红黑树实现。

Collection接口

Collection接口是所有集合接口的根接口,提供了基本的集合操作方法,如添加、删除、迭代等。
常见的Collection实现类有ArrayList、LinkedList和HashSet。

相关方法

  • boolean add(Object o) 向集合中添加一个元素
  • boolean addAll(Collection c) 将指定集合中的所有元素添加到该集合中
  • void clear() 删除该集合中的所有元素
  • boolean remove(Object o) 删除该集合中指定的元素
  • boolean removeAll(Collection c) 删除该集合中包含指定集合c中的所有元素
  • boolean isEmpty() 判断该集合中是否为空
  • boolean contains(Object o) 判断该集合中是否包含某个元素
  • boolean containsAll(Collection c) 判断该集合中是否包含指定集合c中的所有元素
  • int size() 获取该集合元素个数
  • terator iterator 返回在该集合的元素上进行迭代的迭代器(Iterator),用于遍历该集合所有元素
  • Stream stream() 将集合源转换为有序元素的流对象

List接口

List接口是有序集合,允许重复元素。
List接口提供了按照索引操作集合的方法,如get、set和remove等。
常见的List实现类有ArrayList和LinkedList。

ArrayList

ArrayList是Java中常用的基于数组实现的动态数组,它实现了List接口,可以存储任意类型的对象。与普通数组相比,ArrayList具有动态扩容、插入删除元素方便等优势,因此在实际开发中使用较多。

创建ArrayList

ArrayList的创建方式如下:

  • ArrayList list = new ArrayList(); // 无参构造函数
  • ArrayList list = new ArrayList(int initialCapacity); // 指定初始容量的构造函数

其中,E表示泛型参数,可以是任意类型的对象,initialCapacity表示指定的初始容量,如果不指定,则默认为10。

添加元素

ArrayList中添加元素的方法如下:

  • boolean add(E e): 将元素e添加到列表末尾,并返回true
  • void add(int index, E element): 在指定位置index处添加元素element

访问元素

ArrayList中访问元素的方法如下:

  • E get(int index): 返回指定位置index处的元素
  • E set(int index, E element): 将指定位置index处的元素替换为element

删除元素

ArrayList中删除元素的方法如下:

  • E remove(int index): 删除并返回指定位置index处的元素
  • boolean remove(Object o): 删除列表中第一次出现的元素o

查询元素

ArrayList中查询元素的方法如下:

  • boolean contains(Object o): 判断列表是否包含元素o
  • int indexOf(Object o): 返回列表中第一次出现元素o的位置
  • int lastIndexOf(Object o): 返回列表中最后一次出现元素o的位置

遍历元素

ArrayList中遍历元素的方法如下:

for (E e : list) {
// 对元素e进行操作
}

也可以使用迭代器来遍历元素:

Iterator<E> iterator = list.iterator();
while (iterator.hasNext()) {
E e = iterator.next();
// 对元素e进行操作
}

容量管理

ArrayList中容量管理的方法如下:

  • void ensureCapacity(int minCapacity): 增加ArrayList的容量,确保它至少能容纳minCapacity个元素。
  • void trimToSize(): 减小ArrayList的容量,使其等于元素数量。

LinkedList

LinkedList是Java中的双向链表,实现了List接口,可以存储任意类型的对象。与ArrayList相比,LinkedList的插入和删除操作效率更高,但访问元素的效率较低。在实际开发中,如果需要频繁进行插入、删除操作,建议使用LinkedList。

创建LinkedList

LinkedList的创建方式如下:

  • LinkedList list = new LinkedList(); // 无参构造函数

添加元素

LinkedList中添加元素的方法如下:

  • boolean add(E e): 将元素e添加到列表末尾,并返回true
  • void add(int index, E element): 在指定位置index处添加元素element
  • void addFirst(E e): 将元素e添加到列表头部
  • void addLast(E e): 将元素e添加到列表尾部

访问元素

LinkedList中访问元素的方法如下:

  • E get(int index): 返回指定位置index处的元素
  • E getFirst(): 返回列表第一个元素
  • E getLast(): 返回列表最后一个元素

删除元素

LinkedList中删除元素的方法如下:

  • E remove(int index): 删除并返回指定位置index处的元素
  • boolean remove(Object o): 删除列表中第一次出现的元素o
  • E removeFirst(): 删除并返回列表的第一个元素
  • E removeLast(): 删除并返回列表的最后一个元素

查询元素

LinkedList中查询元素的方法如下:

  • boolean contains(Object o): 判断列表是否包含元素o
  • int indexOf(Object o): 返回列表中第一次出现元素o的位置
  • int lastIndexOf(Object o): 返回列表中最后一次出现元素o的位置

遍历元素

LinkedList中遍历元素的方法与ArrayList相同,可以使用foreach循环或迭代器进行遍历。

Set接口

Set接口是不允许重复元素的集合。Set接口中不能有重复元素是因为它使用equals()方法来判断两个元素是否相等,如果两个元素相等,则只能存储一个。
常见的Set实现类有HashSet和TreeSet。

HashSet

HashSet是Java中常用的基于哈希表实现的集合,它是Set接口的一个实现类,可以存储任意类型的对象,并且不允许重复元素。HashSet的查找、插入和删除操作都具有较高的效率,在实际开发中使用较多。

创建HashSet

HashSet的创建方式如下:

  • HashSet set = new HashSet(); // 无参构造函数
  • HashSet set = new HashSet(int initialCapacity); // 指定初始容量的构造函数
  • HashSet set = new HashSet(int initialCapacity, float loadFactor); // 指定初始容量和负载因子的构造函数

其中,E表示泛型参数,可以是任意类型的对象,initialCapacity表示指定的初始容量,如果不指定,则默认为16;loadFactor表示负载因子,如果不指定,则默认为0.75。

添加元素

HashSet中添加元素的方法如下:

  • boolean add(E e): 将元素e添加到集合中,并返回true,如果元素已经存在则返回false

删除元素

HashSet中删除元素的方法如下:

  • boolean remove(Object o): 删除集合中第一次出现的元素o
  • void clear(): 清空集合中的所有元素

查询元素

HashSet中查询元素的方法如下:

  • boolean contains(Object o): 判断集合是否包含元素o

遍历元素

HashSet中遍历元素的方法如下:

for (E e : set) {
// 对元素e进行操作
}

也可以使用迭代器来遍历元素:

Iterator<E> iterator = set.iterator();
while (iterator.hasNext()) {
E e = iterator.next();
// 对元素e进行操作
}

容量管理

HashSet中容量管理的方法如下:

  • int size(): 返回集合中元素的数量
  • boolean isEmpty(): 判断集合是否为空
  • void ensureCapacity(int minCapacity): 增加HashSet的容量,确保它至少能容纳minCapacity个元素。

TreeSet

TreeSet是Java中基于红黑树实现的有序集合,它是SortedSet接口的一个实现类,可以存储任意类型的对象,并且保证元素按照自然顺序或指定的比较器顺序进行排序。TreeSet的插入、删除和查询操作都具有较高的效率,在实际开发中使用较多。

TreeSet是Set接口的另一个实现类,它内部采用平衡二叉树来存储元素,来保证TreeSet集合中没有重复的元素,并且可以对元素进行排序。

二叉树就是每个节点最多有两个子节点的有序树,每个节点及其子节点组成的树称为子树,左侧的节点称为"左子树",右侧的节点称为"右子树",其中左子树上的元素小于它的根结点,而右子树上的元素大于它的根结点。

TreeSet集合没有元素时,新增的第1个元素会在二叉树最顶层;
接着新增元素时,首先会与根结点元素比较;
如果小于根节点元素就与左边的分支比较;
如果大于根节点元素就与右边的分支比较;

创建TreeSet

TreeSet的创建方式如下:

  • TreeSet set = new TreeSet(); // 无参构造函数
  • TreeSet set = new TreeSet(Comparator<? super E> comparator); // 指定比较器的构造函数

其中,E表示泛型参数,可以是任意类型的对象,comparator表示指定的比较器。

添加元素

  • TreeSet中添加元素的方法如下:

  • boolean add(E e): 将元素e添加到集合中,并返回true,如果元素已经存在则返回false

删除元素

TreeSet中删除元素的方法如下:

  • boolean remove(Object o): 删除集合中第一次出现的元素o
  • void clear(): 清空集合中的所有元素

查询元素

TreeSet中查询元素的方法如下:

  • boolean contains(Object o): 判断集合是否包含元素o

遍历元素

TreeSet中遍历元素的方法如下:

for (E e : set) {
// 对元素e进行操作
}

也可以使用迭代器来遍历元素:

Iterator<E> iterator = set.iterator();
while (iterator.hasNext()) {
E e = iterator.next();
// 对元素e进行操作
}

容量管理

TreeSet中容量管理的方法如下:

  • int size(): 返回集合中元素的数量
  • boolean isEmpty(): 判断集合是否为空

Map接口

Map接口是键值对集合。Map接口中的每个元素都包含一个key和一个value,key用来唯一标识一个元素。
常见的Map实现类有HashMap和TreeMap。

HashMap

HashMap是Java中常用的基于哈希表实现的Map,它实现了Map接口,可以存储键值对,并且支持快速的查找、插入和删除操作,在实际开发中使用较多。

创建HashMap

HashMap的创建方式如下:

  • HashMap<K, V> map = new HashMap<K, V>(); // 无参构造函数
  • HashMap<K, V> map = new HashMap<K, V>(int initialCapacity); // 指定初始容量的构造函数
  • HashMap<K, V> map = new HashMap<K, V>(int initialCapacity, float loadFactor); // 指定初始容量和负载因子的构造函数

其中,K表示键的类型,V表示值的类型,initialCapacity表示指定的初始容量,如果不指定,则默认为16;loadFactor表示负载因子,如果不指定,则默认为0.75。

添加元素

HashMap中添加元素的方法如下:

  • V put(K key, V value): 将键值对(key, value)添加到map中,并返回之前与key关联的值,如果没有则返回null

删除元素

HashMap中删除元素的方法如下:

  • V remove(Object key): 根据键key删除map中对应的键值对,返回之前与key关联的值,如果没有则返回null
  • void clear(): 清空map中的所有键值对

查询元素

HashMap中查询元素的方法如下:

  • boolean containsKey(Object key): 判断map中是否包含键key
  • boolean containsValue(Object value): 判断map中是否包含值value
  • V get(Object key): 返回键key对应的值,如果不存在则返回null

遍历元素

HashMap中遍历元素的方法如下:

遍历键:

for (K key : map.keySet()) {
// 对键key进行操作
}

遍历值:

for (V value : map.values()) {
// 对值value进行操作
}

遍历键值对:

for (Map.Entry<K, V> entry : map.entrySet()) {
K key = entry.getKey();
V value = entry.getValue();
// 对键值对(key, value)进行操作
}

容量管理

HashMap中容量管理的方法如下:

  • int size(): 返回map中键值对的数量
  • boolean isEmpty(): 判断map是否为空
  • void ensureCapacity(int minCapacity): 增加HashMap的容量,确保它至少能容纳minCapacity个键值对。

TreeMap

TreeMap是Java中基于红黑树实现的有序Map,它实现了SortedMap接口,可以存储键值对,并且保证按照自然顺序或指定的比较器顺序进行排序。TreeMap的插入、删除和查询操作都具有较高的效率,在实际开发中使用较多。

创建TreeMap

TreeMap的创建方式如下:

  • TreeMap<K, V> map = new TreeMap<K, V>(); // 无参构造函数
  • TreeMap<K, V> map = new TreeMap<K, V>(Comparator<? super K> comparator); // 指定比较器的构造函数

其中,K表示键的类型,V表示值的类型,comparator表示指定的比较器。

添加元素

TreeMap中添加元素的方法如下:

  • V put(K key, V value): 将键值对(key, value)添加到map中,并返回之前与key关联的值,如果没有则返回null

删除元素

TreeMap中删除元素的方法如下:

  • V remove(Object key): 根据键key删除map中对应的键值对,返回之前与key关联的值,如果没有则返回null
  • void clear(): 清空map中的所有键值对

查询元素

TreeMap中查询元素的方法如下:

  • boolean containsKey(Object key): 判断map中是否包含键key
  • boolean containsValue(Object value): 判断map中是否包含值value
  • V get(Object key): 返回键key对应的值,如果不存在则返回null

遍历元素

TreeMap中遍历元素的方法如下:

遍历键:

for (K key : map.keySet()) {
// 对键key进行操作
}

遍历值:

for (V value : map.values()) {
// 对值value进行操作
}

遍历键值对:

for (Map.Entry<K, V> entry : map.entrySet()) {
K key = entry.getKey();
V value = entry.getValue();
// 对键值对(key, value)进行操作
}

容量管理

TreeMap中容量管理的方法如下:

  • int size(): 返回map中键值对的数量
  • boolean isEmpty(): 判断map是否为空

迭代器

迭代器是Collection框架中用于遍历集合的工具。Iterator接口定义了迭代器的基本方法,可以使用它来遍历集合中的元素。

在Java中,Iterator是一种用于遍历集合(Collection)和Map等数据结构的迭代器。它提供了一种统一的遍历方式,使得我们可以在不知道集合内部结构的情况下,逐个访问其中的元素。

获取Iterator

在Java中,获取一个Iterator对象通常有两种方法:

  • 通过集合的iterator()方法获取:

Iterator iterator = collection.iterator();

  • 通过Map的entrySet()方法获取:

Iterator<Map.Entry<K, V>> iterator = map.entrySet().iterator();

遍历集合

使用Iterator遍历集合的基本步骤如下:

使用collection.iterator()方法获取Iterator对象;
使用while循环和hasNext()方法判断是否还有元素可以遍历;
使用next()方法获取下一个元素,并进行相应的操作。
示例代码如下:

Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
// 对元素element进行操作
}

删除元素

在使用Iterator遍历集合时,如果需要删除其中的元素,应该使用Iterator的remove()方法来实现。因为直接使用集合的remove()方法可能会导致并发修改异常(ConcurrentModificationException)。

示例代码如下:

Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
if (needToRemove(element)) {
iterator.remove();
}
}
注意事项

在使用Iterator遍历集合时,需要注意以下几点:

  • 不要在迭代过程中直接修改集合,而是应该通过Iterator的remove()方法来删除元素;
  • 不要多次调用Iterator的next()方法,而是应该将它的返回值保存到一个变量中,以免导致遍历出错;
  • 对于同一个集合,不要同时使用多个Iterator对象进行遍历,否则可能会出现并发修改异常。

泛型

Java中的泛型是指在定义类或接口时,使用类型参数来替代数据类型。这样可以增强代码的可读性和安全性,避免运行时类型转换错误。

Java泛型是一种将数据类型作为参数进行传递的机制,它可以让程序员在编写代码时指定数据类型,使得程序更加灵活、可读性更高、泛化程度更强。泛型可以应用于类、接口、方法等,其中最常见的是泛型类和泛型方法。

  • 泛型类
    泛型类是一种具有泛型参数的类,可以在定义类时通过<>符号来指定泛型参数,如下所示:
public class MyClass<T> {
private T data;
public void setData(T data) {
this.data = data;
}
public T getData() {
return data;
}
}

在上述示例中,MyClass类拥有一个泛型参数T,使用setData()方法和getData()方法对data进行赋值和读取,这两个方法的返回值和参数类型都是T类型。

  • 泛型方法
    泛型方法是一种具有泛型参数的方法,可以在定义方法时通过<>符号来指定泛型参数,如下所示:
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.println(element);
}
}

在上述示例中,printArray()方法拥有一个泛型参数T,它可以接受任意类型的数组,并使用for-each循环遍历数组中的元素。

  • 通配符
    通配符是一种特殊的泛型参数,用于表示未知的数据类型。Java中有三种通配符:?、? extends T和? super T。
  1. ?表示任意类型的数据;
  2. ? extends T表示T类型或T的子类;
  3. ? super T表示T类型或T的父类。
    通配符常用于方法的参数类型或返回值类型中,以增加程序的灵活性和泛化程度。
  • 泛型限制
    在使用泛型时,有时需要对泛型类型进行限制,以确保程序的正确性和安全性。Java中可以通过extends和super关键字来对泛型类型进行限制。

在泛型类或泛型方法中,使用extends关键字对泛型类型进行上限限制:

public class MyClass<T extends Number> {
// ...
}

上述示例中,MyClass类对泛型类型T进行了上限限制,使得T只能是Number类型或其子类型。

在泛型方法中,使用super关键字对泛型类型进行下限限制:

public static <T> void copy(List<? super T> dest, List<? extends T> src) {
for (T element : src) {
dest.add(element);
}
}

上述示例中,copy()方法对dest集合中元素的类型进行了下限限制,使得它只能是T类型或T的父类型。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳住

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值