1.Java集合框架
架构图:
Java的集合框架是一组用于存储和操作数据的类和接口。它提供了各种数据结构,如列表、集合、映射等,以及用于操作这些数据结构的算法和工具。Java集合框架位于Java.util包中,并且是Java编程中常用的核心组件之一。
Java集合框架主要包括以下接口和类:
Collection接口:它是集合框架中最基本的接口,定义了一组操作集合的方法,如添加、删除、迭代、查询等。
List接口:继承自Collection接口, List接口存储一组不唯一,有序(插入顺序)的对象。List的实现类有ArrayList、LinkedList。
Set接口:继承自Collection接口,Set接口存储一组唯一,无序的对象。常见的实现类有HashSet、TreeSet。
Map接口:存储一组键值对像,提供key到value的映射。常见的实现类有HashMap、TreeMap和LinkedHashMap。
2.Collection接口
接口是Java集合框架中的顶层接口之一,它表示一组对象的集合。它是一个通用的接口,可以用来存储任意类型的对象。
Collection接口定义了一些基本的方法,用于添加、删除、查询和遍历集合中的元素。它提供了一种统一的方式来操作集合,无论具体的实现类是什么。
常用方法:
boolean add(a) | 向当前集合中添加元素a,成功添加返回true |
---|---|
boolean addAll(Collection<? extends E> collection) | 向当前集合中添加指定集合中的所有元素,成功添加返回true |
boolean remove(Object e) | 从当前集合中删除指定的元素 |
boolean removeAll(Collection<?> collection) | 删除当前集合中与指定集合中相同的元素。 |
boolean retainAll(Collection<?> collection) | 保留当前集合中与指定集合中相同的元素,删除其他元素。 |
void clear() | 清空集合中的所有元素。 |
boolean contains(Object element) | 判断集合中是否包含指定的元素。 |
boolean containsAll(Collection<?> collection) | 判断当前集合是否包含指定集合中的所有元素。 |
boolean isEmpty() | 判断集合是否为空。 |
int size() | 返回集合中元素的个数。 |
Object[] toArray() | 将集合转换为数组。 |
Iterator<E> iterator() | 返回一个迭代器,用于遍历集合中的元素。 |
3.list接口里的ArrayList实现类和LinkedList实现类
ArrayList实现类实现了长度可变的数组,在内存中分配连续的空间,遍历元素和随机访问的效率比较高。
LinkedList实现类采用链表存储方式,插入、删除元素时效率比较高。
ArrayList集合类
相比于LinkedList我们经常使用ArrayList
Array有三种遍历方式,都在下面代码里。
常用方法(方法名里的第一个是返回值,第二个才是方法名)
方法名 | 作用 |
---|---|
boolean add (Ocbject o) | 在列表的末尾添加元素,起始位置从0开始 |
void add(int index,Object o) | 在指定的索引位置添加元素。索引必须介于0和列表中元素个数之间 |
int size() | 返回列表中的元素个数 |
Object get(int index) | 返回指定索引位置处的元素。取出的元素是Object类型,使用前需要进行强制类型转换 |
boolean contains(Object o) | 判断列表中是否存在指定元素 |
Object remove(int index) | 从列表中删除指定位置元素,起始索引位置从0开始 |
boolean clear() | 清空列表中的所有元素,返回true |
boolean isEmpty() | 判断列表是否为空,如果为空则返回true |
Iterator<E> iterator() | 返回一个迭代器,用于遍历列表中的元素 |
Object[] toArray() | 将列表中的元素以数组形式返回 |
补充:retainAll()
lista.retainAll(listb)
retainAll()方法是List接口的一个方法,用于保留两个列表中相同的元素。换句话说,它从lista中删除所有不包含在listb中的元素。
Iterator这个E是泛型,后面介绍
List list = new ArrayList();
Animal a = new Animal("小猫", 13);
Animal b = new Animal("小狗", 15);
Animal c = new Animal("小猪", 10);
//添加
list.add(a);
list.add(1, b);
list.add(2, c);
//删除
list.remove(1);
list.remove("小猪");
//list.clear();清空
//修改
list.set(1, new Animal("小鹅", 16));
//插入
list.add(1, new Animal("小羊", 6));
//查询
System.out.println("ArrayList里有" + list.size() + "只动物");
Animal animale = (Animal) list.get(0);
System.out.println("第一个动物是" + animale.getName());
if (list.contains(a)) {
System.out.println("ArrayList里有小猫");
}
System.out.println("--------------");
//遍历
//for循环遍历
for (int i = 0; i < list.size(); i++) {
Animal animal = (Animal) list.get(i);
System.out.println(animal.getName() + " " + animal.getAge());
}
System.out.println("--------------");
//加强for循环遍历
for (Object animals : list) {
Animal animal = (Animal) animals;
System.out.println(animal.getName() + " " + animal.getAge());
}
System.out.println("--------------");
//迭代器
Iterator<Animal> it = list.iterator();
while (it.hasNext()) {
Animal animal = (Animal) it.next();
System.out.println(animal.getName() + " " + animal.getAge());
}
System.out.println("--------------");
//判断是否为空
System.out.println(list.isEmpty());
//类型转换
list.toArray();
List接口类的LinkedList实现类
插入或删除元素时比ArrrayList快
方法名 | 作用 |
---|---|
void addFirst(Object o) | 在列表的首部添加元素 |
void addLast(Object o) | 在列表的末尾添加元素 |
Object getFirst() | 返回列表中的第一个元素 |
Object getLast() | 返回列表中的最后一个元素 |
Object removeFirst() | 删除并返回列表中的最后一个元素 |
Object removeLast() | 删除并返回列表中的最后一个元素 |
LinkedList list = new LinkedList();
Animal a = new Animal("小猫", 13);
Animal b = new Animal("小狗", 15);
Animal c = new Animal("小猪", 10);
//增加
list.add(a);
list.addFirst(b);
list.addLast(c);
//获取
Animal li = (Animal) list.getFirst();
System.out.println(li.getName());
Animal li2 = (Animal) list.getLast();
System.out.println(li2.getName());
Animal li3 = (Animal) list.get(2);
System.out.println(li3.getName());
//删除
list.remove(0);
list.remove("小猪");
list.removeLast();
list.removeFirst();
list.clear();
list.removeAll(list);
//迭代器遍历
Iterator it = list.iterator();
while (it.hasNext()) {
Animal animal = (Animal) it.next();
System.out.println(animal.getName() + " " + animal.getAge());
}
//for循环遍历
for (int i = 0; i < list.size(); i++) {
Animal animal = (Animal) list.get(i);
System.out.println(animal.getName()+" "+animal.getAge());
}
//增强for循环遍历
for(Object animal: list){
Animal animal1 = (Animal) animal;
System.out.println(animal1.getName()+" "+animal1.getAge());
浅浅分析一下ArrayList和LinkedList有什么异同
相同点:都是Java集合框架Collection接口下List接口的两个实现类,都是存放
一组不唯一,有序的对象。
不同点:存放方式不同,
ArrayList使用一个可变大小的数组来存储元素。它支持快速随机访问和按索引访问元素,因为它可以根据索引直接计算出元素的位置。但是,在删除或插入元素时,需要对后续元素进行移动,因为数组的大小是固定的。这可能会导致性能下降,特别是当操作集合中的大量元素时。
LinkedList使用**双向链表来存储元素。**在插入或删除元素时,只需要更改相邻节点的引用,而不需要移动其他元素。这使得插入和删除操作更快。然而,访问元素的速度较慢,因为需要遍历链表来找到特定索引的元素。
所以,ArrayList遍历元素和随机访问元素的效率比较高,LinkedList插入 、删除元素时效率比较高。
4.Set接口
Set接口存放一组唯一、无序的对象,Set存放的是对象的引用,Set接口里的元素是通过equals方法比较确定是否唯一的,HashSet是Set接口常用的实现类。
注意Set接口里不存在get()方法
public class TestSetequals {
public static void main(String[] args) {
Set set = new HashSet();
String s1 = new String("java");
String s2 = s1;
System.out.println(s1 == s2);
String s3 = new String("java");
System.out.println(s1 == s3);
System.out.println(s1.equals(s3));//String类重写了Object类的equals方法,set比较元素是通过equals的方法。
set.add(s1);
set.add(s2);
set.add(s3);
System.out.println(set.size());//Set接口存储一组唯一,无序的对象
}
}
###HashSet实现类
HashSet是Java中的一种集合实现类,它基于哈希表实现。HashSet中的元素是无序的,不允许重复,并且允许使用null元素。
常用方法:
方法名 | 作用 |
---|---|
add(element) | 将指定的元素添加到集合中,如果元素已经存在,则不会进行任何操作。 |
addAll(collection) | 将指定集合中的所有元素添加到集合中。 |
remove(element) | 从集合中移除指定的元素,如果元素不存在,则不会进行任何操作。 |
removeAll(collection) | 从集合中移除指定集合中包含的所有元素。 |
contains(element) | 判断集合中是否包含指定的元素。 |
isEmpty() | 判断集合是否为空。 |
size() | 返回集合中元素的个数。 |
clear() | 清空集合中的所有元素。 |
iterator() | 返回一个迭代器,用于遍历集合中的元素 |
public static void main(String[] args) {
Set list = new HashSet();
Animal a = new Animal("小猫", 13);
Animal b = new Animal("小狗", 15);
Animal c = new Animal("小猪", 10);
//增加
list.add(a);
list.add(b);
list.add(c);
//获取元素个数
System.out.println(list.size());
//删除
list.remove(a);
// list.clear();
// list.removeAll(list);
//遍历:
Iterator it = list.iterator();//迭代器遍历
while (it.hasNext()) {
Animal animal =(Animal) it.next();
System.out.println(animal.getName());
}
System.out.println("--------------");
for (Object s : list) {//增强for循环遍历
Animal animal = (Animal) s;
System.out.println(animal.getName());
}
因为没有Set接口没有get()方法,所以只有增强for循环和迭代器循环两种!
5.迭代器循环的逻辑:
1.创建一个Iterator的实例。
2.在for循环里用boolean hasNext()方法判断是否存在另一个可访问的元素,然后用Object next返回要访问的元素。
Iterator it = list.iterator();
while (it.hasNext()) {
Animal animal = (Animal) it.next();
System.out.println(animal.getName() + " " + animal.getAge());
}
6.泛型
泛型是一种约束,泛型的本质是参数化类型,也就是说将要操作的数据类型指定为一个参数,用泛型约束数据。
ArrayList<String> list = new ArrayList<String>();
List list2 = new ArrayList();
list2.add("张三");
list2.add("李四");
list2.add(1, "王五");
System.out.println(list2.size());
for (int i = 0; i < list2.size(); i++) {
// String name = (String) list2.get(i);泛型将其约束为String
System.out.println(list2.get(i));
}
for (Object s : list2) {
System.out.println(s);
}
System.out.println("--------------");
Iterator it = list2.iterator(); //用while循环
while (it.hasNext()) {
// String name = (String) it.next();
System.out.println(it.next());
}
System.out.println("--------------");
System.out.println("是否包含王五:" + list2.contains("王五"));
list2.remove(1);
list2.remove("张三");