Java_Collection集合总结

list集合排序

Collections.sort(List<T> list)

要重写Comparable接口中的compareTo方法

Collections.sort(List<T> list,Comparator<? super T>)

要从写Comparator类中的compare方法

使用匿名内部类重写

往集合添加元素

Collections.addAll(Collection<T> c, T... elements)

打乱集合顺序

Collections.shuffle(List<?> list)

集合

1.集合是java中提供的一种容器,可以用来存储多个数据。

2.长度是可变的.

3.存储的元素是对象

集合框架介绍

存储结构可以分为两大类

1.单列集合java.util.Collection

2.双列集合java.util.Map

Collection是单列集合类的根接口

Collection有两个子接口:

  1. java.util.List
  2. java.util.Set

List的特点是元素有序、元素可重复 .

Set的特点是元素无序,而且不可重复。

List接口的主要实现类有

1.java.util.ArrayList

2.java.util.LinkedList

Set接口的主要实现类有

1.java.util.HashSet

2.java.util.TreeSet

单列集合共性的方法

public boolean add(E e):把给定的对象添加到当前集合中 。
public void clear() :清空集合中所有的元素。
public boolean remove(E e): 把给定的对象在当前集合中删除。
public boolean contains(E e): 判断当前集合中是否包含给定的对象。
public boolean isEmpty(): 判断当前集合是否为空。
public int size(): 返回集合中元素的个数。
public Object[] toArray(): 把集合中的元素,存储到数组中。

Iterator接口

迭代器(对集合进行遍历)

迭代器的使用步骤(重点):

1.使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态)

Iterator<类名> it = 集合对象.iterator();

2.使用Iterator接口中的方法hasNext判断还有没有下一个元素

1
2
while(it.hasNext()){
}

3.使用Iterator接口中的方法next取出集合中的下一个元素

1
类名 o = it.next();

增强for循环

底层使用的也是迭代器

JDK1.5之后出现的新特性

所有的单列集合都可以使用增强for

public interface Iterable<T>实现这个接口允许对象成为 “foreach” 语句的目标

1
2
3
for(集合/数组的数据类型 变量名: 集合名/数组名){
sout(变量名);
}

泛型的概念

泛型是一种未知类型,当不确定使用什么类型的时候,可以使用泛型

定义和使用含有泛型的类

1
2
3
修饰符 class 类名<代表泛型的变量>
{
}

定义和使用含有泛型的方法

泛型定义在方法的修饰符和返回值类型之间

含有泛型的方法,在调用方法的时候确定泛型的数据类型
传递什么类型的参数,泛型就是什么类型

1
2
3
修饰符 <泛型> 返回值类型 方法名(参数列表(使用泛型)){
方法体;
}

定义和使用含有泛型的接口

1
2
修饰符 interface 接口名<代表泛型的变量> { 
}
使用有两种方法

1.在实现类中指定泛型接口类型

1
2
public class A implements 接口名<String>{
}

2.接口使用什么泛型,类就使用什么泛型

1
2
修饰符 interface 接口名<T> { 
}
1
2
public class A<T> implements 接口名<T>{
}

泛型通配符

使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示 .

使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。

?:代表任意的数据类型

不能创建对象使用
只能作为方法的参数使用

泛型的上限

格式类型名称 对象名称

意义: 只能接收该类型及其子类

泛型的下限

格式类型名称 对象名称

意义只能接收该类型及其父类型

1
2
public static void printArray(ArrayList<?> list){
}
1
2
3
4
5
// 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
public static void getElement1(Collection<? extends Number> coll){}

// 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
public static void getElement2(Collection<? super Number> coll){}

数据结构

链表

查询慢,增删快.

数组

查询快,增删慢.

队列

先进先出

先进后出

红黑树

  1. 节点可以是红色的或者黑色的
  2. 根节点是黑色的
  3. 叶子节点(空节点)是黑色的
  4. 每个红色节点的字节点都是黑色的
  5. 任何一个节点到每一个叶子节点的所有路径上黑色节点相同

List集合常用方法

public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。

public E get(int index):返回集合中指定位置的元素。

public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。

public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。

索引越界异常

IndexOutOfBoundsException:索引越界异常,集合会报
ArrayIndexOutOfBoundsException:数组索引越界异常
StringIndexOutOfBoundsException:字符串索引越界异常

ArrayList集合

使用的是数组结构,查询快,增删慢

LinkedList集合

数据存储的结构是链表结构 ( 双向链表 )

方便元素添加、删除的集合

public void addFirst(E e):将指定元素插入此列表的开头。

public void addLast(E e):将指定元素添加到此列表的结尾。

public E getFirst():返回此列表的第一个元素。

public E getLast():返回此列表的最后一个元素。

public E removeFirst():移除并返回此列表的第一个元素。

public E removeLast():移除并返回此列表的最后一个元素。

public E pop():从此列表所表示的堆栈处弹出一个元素。

public void push(E e):将元素推入此列表所表示的堆栈。

public boolean isEmpty():如果列表不包含元素,则返回true。

public E remove(int index) 移除此列表中指定位置处的元素。将任何后续元素向左移(从索引中减 1)。返回从列表中删除的元素。

HashSet集合

Set接口的一个实现类

存储的元素是不可重复的

元素都是无序的

底层的实现其实是一个java.util.HashMap支持

根据对象的哈希值来确定元素在集合中的存储位置

保证元素唯一性的方式依赖于:hashCodeequals方法

哈希值

JDK1.8之前,哈希表底层采用数组+链表实现的

JDK1.8 以后, 哈希表存储采用数组+链表+红黑树实现 ,当链表长度超过阈值(8)时,将链表转换为红黑树

自定义的类需要重写 hashCode和equals方法 保证对象其唯一

Set集合存储元素不重复的原理

set集合在调用add时会调用hashCode()和equals()判断元素是否重复

hashCode()会生成一个哈希值并存储在数组里

如果哈希值相同,称为哈希冲突,会在哈希值对应的链表或红黑树中查看元素是否相同,如果相同则抛弃

HashSet存储自定义类型元素

HashSet存储自定义类型元素

set集合报错元素唯一:
存储的元素(String,Integer,…Student,Person…),必须重写hashCode方法和equals方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Person {

private int age;
private String name;

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
//下面是比较元素
return age == person.age &&
Objects.equals(name, person.name);
}

@Override
public int hashCode() {

return Objects.hash(name, age);
}
}

LinkedHashSet集合

java.util.LinkedHashSet集合 extends HashSet集合
LinkedHashSet集合特点:
底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的存储顺序),保证元素有序

LinkedHashSet<String> linked = new LinkedHashSet<>();

可变参数

​ 可变参数底层就是一个数组

1.一个方法的参数列表,只能有一个可变参数
2.如果方法的参数有多个,那么可变参数必须写在参数列表的末尾

1
2
3
修饰符 返回值类型 方法名(数据类型...变量名){

}

Collections集合工具类的方法addAll和shuffle

java.utils.Collections是集合工具类,用来对集合进行操作。部分方法如下:
public static <T> boolean addAll(Collection<T> c, T... elements):往集合中添加一些元素。
public static void shuffle(List<?> list)打乱顺序:打乱集合顺序。

1
2
Collections.addAll(list,"a","b","c","d","e");
Collections.shuffle(list);

Collections集合工具类的方法sort(List)

两个对象比较的结果有三种:大于,等于,小于。

如果要按照升序排序,
则o1 小于o2,返回(负数),相等返回0,01大于02返回(正数)
如果要按照降序排序
则o1 小于o2,返回(正数),相等返回0,01大于02返回(负数)

public static<T> void sort(List<T> list):将集合中元素按照默认规则排序

sort(List<T> list)使用前提
被排序的集合里边存储的元素,必须实现Comparable,重写接口中的方法compareTo定义排序的规则

1
Collections.sort(list01);//默认是升序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Person implements Comparable<Person>{

private int age;
public int getAge() {
return age;
}
//重写排序的规则
@Override
public int compareTo(Person o) {
//return 0;//认为元素都是相同的
//自定义比较的规则,比较两个人的年龄(this,参数Person)
//return this.getAge() - o.getAge();//年龄升序排序
//年龄降序排序公式: -(o.getAge() - this.getAge())
return o.getAge() - this.getAge();//年龄升序排序
}
}

Collections集合工具类的方法sort(List,Comparator)

java.utils.Collections是集合工具类,用来对集合进行操作。部分方法如下:
public static <T> void sort(List<T> list,Comparator<? super T> ):将集合中元素按照指定规则排序。

Comparator:相当于找一个第三方的裁判,比较两个

Comparator的排序规则:
o1-o2:升序

o2 - o1 降序

1
2
3
4
5
6
7
8
Collections.sort(list01, new Comparator<Integer>() {
//重写比较的规则
@Override
public int compare(Integer o1, Integer o2) {
//return o1-o2;//升序
return o2-o1;//降序
}
});
1
2
3
4
5
6
7
8
9
10
11
12
//扩展:了解
Collections.sort(list02, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
//按照年龄升序排序
int result = o1.getAge()-o2.getAge();
//如果两个人年龄相同,再使用姓名的第一个字比较
if(result==0){
result = o1.getName().charAt(0)-o2.getName().charAt(0);
}
return result;
}