集合
1 集合和数组的区别
1.1数组
类型确定,长度固定
不适合元素个数和类型不确定的业务场景,更不适合做增删数据操作
1.2集合
大小不固定,启动后可以动态变化,类型也可以选择不固定
1.3 集合中存储的是元素的什么信息?
集合中存储的是元素对象的地址。
2集合的分类
2.1 集合包括
单列Collection + 双列 Map
单列Collection集合包括List + Set
List :ArrayList + LinkedList
特点:添加的元素是有序,可重复,又索引
Set: HashSet <== LinkedHashSet TreeSet
特点:
HashSet : 无序、不重复,无索引
LinkedHashSet:有序、不重复、无索引
TreeSet:按照大小默认升序排序、不重复、无索引。
Collection API
Collection<Integer> arrayList = new ArrayList<Integer>();
Collection<Integer> linkedList = new LinkedList<Integer>();
Collection<Integer> hashSet = new HashSet<Integer>();
Collection<Integer> treeSet = new TreeSet<Integer>();
// public boolean add(E e) 把给定的对象添加到当前集合中
arrayList.add(1);
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
linkedList.add(1);
linkedList.add(1);
linkedList.add(3);
linkedList.add(2);
// public void clear() 清空集合中所有的元素
arrayList.clear();
System.out.println(arrayList);
// public boolean remove(E e) 把给定的对象在当前集合中删除删除第一个出现的值
linkedList.remove(1);
System.out.println(linkedList);
// public boolean contains(Object obj) 判断当前集合中是否包含给定的对象
System.out.println(linkedList.contains(1));
// public boolean isEmpty() 判断当前集合是否为空
System.out.println(linkedList.isEmpty());
System.out.println(arrayList.isEmpty());
// public int size() 返回集合中元素的个数。
System.out.println(linkedList.size());
// public Object[] toArray() 把集合中的元素,存储到数组中
Object[] array = linkedList.toArray();
System.out.println(array.toString());
集合遍历
// 定义数组 [1, 2, 3, 2]
Collection<Integer> arraylist = new ArrayList<Integer>();
// add 1, 2, 3, 2
arraylist.add(1);
arraylist.add(2);
arraylist.add(3);
arraylist.add(2);
// 遍历方法一
// 使用遍历迭代器方法 Iterator
// Iterator<E> iterator() 返回集合中的迭代器对象,该迭代器对象默认指向当前集合的0索引
// 迭代器如果取元素越界会出现什么问题。
// 会出现NoSuchElementException异常。
System.out.println("遍历迭代器遍历");
Iterator<Integer> iterator = arraylist.iterator();
while(iterator.hasNext()){
Integer next = iterator.next();
System.out.println(next);
}
// 遍历方法二
// foreach/增强for循环
System.out.println("foreach/增强for循环");
for(Integer i : arraylist){
System.out.println(i);
}
// 遍历方法三 Lambda表达式遍历集合
System.out.println("Lambda表达式遍历集合");
arraylist.forEach(e -> {
System.out.println(e);
});
List特有APi
- List集合因为支持索引,所以多了很多索引操作的独特api,其他Collection的功能List也都继承了
方法名称 | 说明 |
---|---|
void add(int index,E element) | 在此集合中的指定位置插入指定的元素 |
E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
E get(int index) | 返回指定索引处的元素 |
ArrayList<Integer> arrayList = new ArrayList<>();
// 添加元素
arrayList.add(1);
arrayList.add(4);
arrayList.add(12);
arrayList.add(6);
System.out.println(arrayList);//[1, 4, 12, 6]
// void add(int index,E element) 在此集合中的指定位置插入指定的元素
arrayList.add(1, 2);
System.out.println(arrayList); //[1, 2, 4, 12, 6]
// E remove(int index) 删除指定索引处的元素,返回被删除的元素
arrayList.remove(4);
System.out.println(arrayList);// [1, 2, 4, 12]
// E set(int index,E element) 修改指定索引处的元素,返回被修改的元素
arrayList.set(2, 3);
System.out.println(arrayList); // [1, 2, 3, 12]
// E get(int index) 返回指定索引处的元素
Integer integer = arrayList.get(1);
System.out.println(integer); // 2
List特有的遍历
ArrayList<Integer> arrayList = new ArrayList<>();
// 添加元素
arrayList.add(1);
arrayList.add(4);
arrayList.add(12);
arrayList.add(6);
for(int i = 0; i < arrayList.size(); i ++ )
{
System.out.println(arrayList.get(i));
}
ArrayList集合底层原理
- ArrayList底层是基于数组实现的:根据索引定位元素快,增删需要做元素的移位操作。
- 第一次创建集合并添加第一个元素的时候,在底层创建一个默认长度为10的数组。
所以ArrayList 查询快、增删元素相对较慢。
LinkedList的特点
- 底层数据结构是双链表,查询慢,首尾操作的速度是极快的,所以多了很多首尾操作的特有API。
方法名称 | 说明 |
---|---|
public void addFirst(E e) | 在该列表开头插入指定的元素 |
public void addLast(E e) | 将指定的元素追加到此列表的末尾 |
public E getFirst() | 返回此列表中的第一个元素 |
public E getLast() | 返回此列表中的最后一个元素 |
public E removeFirst() | 从此列表中删除并返回第一个元素 |
public E removeLast() | 从此列表中删除并返回最后一个元素 |
LinkedList<Integer> linkedList = new LinkedList<Integer>();
linkedList.add(1);
linkedList.add(2);
linkedList.add(4);
linkedList.add(3);
// public void addFirst(E e) 在该列表开头插入指定的元素
linkedList.addFirst(2);
System.out.println(linkedList); // [2, 1, 2, 4, 3]
// public void addLast(E e) 将指定的元素追加到此列表的末尾
linkedList.addLast(5);
System.out.println(linkedList); // [2, 1, 2, 4, 3, 5]
// public E getFirst() 返回此列表中的第一个元素
Integer integer = linkedList.getFirst();
System.out.println(integer); // 2
// public E getLast() 返回此列表中的最后一个元素
integer = linkedList.getLast();
System.out.println(integer); // 5
// public E removeFirst() 从此列表中删除并返回第一个元素
linkedList.removeFirst();
System.out.println(linkedList); // [1, 2, 4, 3, 5]
// public E removeLast() 从此列表中删除并返回最后一个元素
linkedList.removeLast();
System.out.println(linkedList); // [1, 2, 4, 3]
存在问题:
当我们从集合中找出某个元素并删除的时候可能出现一种并发修改异常问题。
- 迭代器遍历集合且直接用集合删除元素的时候可能出现。
- 增强for循环遍历集合且直接用集合删除元素的时候可能出现。
哪种遍历且删除元素不出问题
- 迭代器遍历集合但是用迭代器自己的删除方法操作可以解决。
- 使用for循环遍历并删除元素不会存在这个问题。
Set系列集合
HashSet
特点
- 无序、不重复、无索引。
LinkedHashSet
- 有序、不重复、无索引。
TreeSet
特点
- 排序、不重复、无索引。
注意 - 想要使用TreeSet存储自定义类型,需要制定排序规则
- 让自定义的类(如学生类)实现Comparable接口重写里面的compareTo方法来定制比较规则。
public class User implements Comparable<Integer>{
Integer id;
String name;
public User() {
}
public User(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
@Override
public int compareTo(Integer o) {
return this.id - o;
}
}
-
- TreeSet集合有参数构造器,可以设置Comparator接口对应的比较器对象,来定制比较规则。(主要)
public class UserComparator implements Comparator<User> {
@Override
public int compare(User o1, User o2) {
return o1.id - o2.id;
}
}
Collection集合工具类
- java.utils.Collections:是集合工具类
- 作用:Collections并不属于集合,是用来操作集合的工具类。
方法名称 | 说明 |
---|---|
public static boolean addAll(Collection<? super T> c, T… elements) | 给集合对象批量添加元素 |
public static void shuffle(List<?> list) | 打乱List集合元素的顺序 |
public static void sort(List list) | 将集合中元素按照默认规则排序 |
public static void sort(List list,Comparator<? super T> c) | 将集合中元素按照指定规则排序 |
public static void main(String[] args) {
HashSet<Integer> hashSet = new HashSet<Integer>();
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(4);
arrayList.add(3);
// public static <T> boolean addAll(Collection<? super T> c, T... elements) 给集合对象批量添加元素
boolean b = Collections.addAll(hashSet, 1, 4 , 3);
System.out.println(b);
System.out.println(hashSet);
// public static void shuffle(List<?> list) 打乱List集合元素的顺序
Collections.shuffle(arrayList);
System.out.println(arrayList);
// public static <T> void sort(List<T> list) 将集合中元素按照默认规则排序
Collections.sort(arrayList);
System.out.println(arrayList);
// public static <T> void sort(List<T> list,Comparator<? super T> c) 将集合中元素按照指定规则排序
}
Map集合体系
- Map集合是一种双列集合,每个元素包含两个数据。
- Map集合的每个元素的格式:key=value(键值对元素)。
- Map集合也被称为“键值对集合”。
整体格式 - Map集合的完整格式:{key1=value1 , key2=value2 , key3=value3 , …}