目录
集合
注:黄色为接口,白色为实现类
一、Collection接口
Collection接口是集合类的基本接口之一
(1)基本方法
方法 | 说明 |
---|---|
boolean add(E e) | 添加元素 |
boolean addAll(Collection<? extends E> c) | 指定集合中的所有元素添加到此集合 |
boolean remove(Object o) | 删除元素 |
Iterator< E> iterator() | 返回迭代器 |
int size() | 集合元素个数 |
void clear() | 删除所有元素 |
boolean contains(Object o) | 集合中是否包含该元素 |
boolean containsAll(Collection<?> c) | 集合中是否包含该集合所有元素 |
boolean isEmpty() | 是否为空集合 |
< T> T[] toArray(T[] a) | 集合转数组 |
(2) 遍历操作
Collection<String> c = new.....
// 迭代器遍历
Iterator<String> it = c.iterator();
while (it.hasNext()){
String s = it.next()
System.out.println(s);
}
// foreach 遍历
for (String s : c) {
System.out.println(s);
}
// java8中,使用forEachRemaining()方法
Iterator<String> ite = c.iterator();
ite.forEachRemaining(System.out::println);
迭代器删除元素,next方法和remove方法的调用具有相互依赖性,调用remove方法之前必须调用next方法
Iterator<String> it = c.iterator();
it.next()
it.remove() // 此时删除的是第一个元素的值
迭代器修改元素时,set方法时用一个新元素替换next方法返回的上一个元素
Iterator<String> it = c.iterator();
it.next()
it.set()// 此时设置的是第一个元素的值
(3) 集合转数组
Collection<String> c = new ArrayList<>();
c.add("a");
c.add("b");
c.add("c");
// 转为数组
String[] s = c.toArray(new String[c.size()]);
二、List集合
List(有序集合)
(1)特点及方法
- 有序:存储和取出的元素顺序一致
- 可重复:存储的元素可重复
特有方法:
方法 | 说明 |
---|---|
void add(int index, E element) | 在列表的指定位置插入元素 |
E remove(int index) | 删除指定位置的元素 |
E set(int index, E element) | 修改指定位置的元素 |
E get(int index) | 返回列表指定位置的元素 |
(2)并发修改异常
在使用迭代器添加元素时,修改了集合中元素的长度,造成了迭代器获取元素时预期与实际不一致,造成ConcurrentModificationException并发修改异常。(由于foreach本质也是Iterator迭代器,所以同样会报错)
解决方案:1. 使用传统for循环 2.使用列表迭代器ListIterator
public class ListTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
// 错误!!
Iterator<String> it = list.listIterator();
while (it.hasNext()) {
String s = it.next();
if (s.equals("c")){
list.add("d");
}
}
// 方法一:
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
if (s.equals("c"))
list.add("d");
}
// 方法二:
ListIterator<String> iterator = list.listIterator();
while (iterator.hasNext()) {
String s = iterator.next();
if (s.equals("c")){
iterator.add("d");
}
}
}
}
(3)数组与链表
数组(ArrayList):查询快,增删慢
链表(LinkedList):查询慢,增删快
两种访问元素方法:
迭代器和随机访问(使用get和set方法按索引访问),随机访问不适合链表,但对数组很有用
3.1 ArrayList数组
3.2 LinkedList链表
特有方法:
方法 | 说明 |
---|---|
void addFirst(E e) | 在列表开头插入 |
void addLast(E e) | 在列表末尾插入 |
E getFirst() | 取得第一个元素 |
E getLast() | 取得最后一个元素 |
E removeFirst() | 删除并返回第一个元素 |
E removeLast() | 删除并返回最后一个元素 |
三、Set集合
(1)特点及方法
- 不包含重复元素
- 无索引,不可使用普通for循环遍历
(2)HashSet集合
2.1 特点
- 不包含重复元素
- 无索引,不能使用普通的for循环
- 对集合迭代顺序不做保证,不保证存储和取出的顺序一致
- 底层数据结构是哈希表
2.2 哈希表
每个列表别成为哈希桶,默认为16个。如果哈希表太满,就需要再散列,装填因子决定何时进行再散列(一般为0.75)。若超过,则这个表会用双倍的桶数自动再散列
2.3 注意
为保证不包含重复元素,需要重写类中的equals方法和hashCode方法
public class HashSetTest {
public static void main(String[] args) {
Person p1 = new Person("a", 99);
Person p2 = new Person("b",20);
Person p3 = new Person("a", 99);
HashSet<Person> people = new HashSet<>();
people.add(p1);
people.add(p2);
people.add(p3);
for (Person person : people) {
System.out.println(person);
}
}
}
(3)LinkedHashSet
3.1 特点
- 由链表和哈希表实现
- 链表保证元素有序
- 哈希表保证元素不重复
(4)TreeSet
4.1 特点
- 元素有序:这里的有序不是指存取顺序,而是按规则排序(任意顺序),取决于构造方法
- TreeSet() :根据自然排序
- TreeSet(Comparator comparator):根据比较器排序
4.2 自然排序Comparable使用
代码示例:
要求为按照年龄排序,若相同则按照姓名排序
public class People implements Comparable<People>{
private String name;
private int age;
public People(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(People o) {
// 主要条件
int num1 = this.age - o.age;
// 次要条件
int num2 = num1==0? this.name.compareTo(o.name):num1;
return num2;
// if (num1==0)
// return this.name.compareTo(o.name);
// else
// return num1;
}
}
需要在People类中需要实现Comparable接口并重写compareTo()方法
注意:需要指定主要条件和次要条件,否则会造成年龄相同,姓名不同的两个人误认为同一个人而无法存储
一定注意次要条件!!!!!
public class TreeSetTest {
public static void main(String[] args) {
People a = new People("a", 10);
People b = new People("b", 20);
People c = new People("c", 30);
People d = new People("d", 10);
TreeSet<People> people = new TreeSet<>();
people.add(a);
people.add(b);
people.add(c);
people.add(d);
for (People person : people) {
System.out.println(person.getName()+","+person.getAge());
}
}
}
4.3 比较器排序Comparator使用
需要让TreeSet接收Comparator实现类
一定注意次要条件!!!!!
public class TreeSetTest {
public static void main(String[] args) {
People a = new People("a", 10);
People b = new People("b", 20);
People c = new People("c", 30);
People d = new People("d", 10);
TreeSet<People> people = new TreeSet<>(new Comparator<People>() {
@Override
public int compare(People o1, People o2) {
//主要条件
int num1=o1.getAge()-o2.getAge();
//次要条件
return num1==0? o1.getName().compareTo(o2.getName()) : num1;
}
});
people.add(a);
people.add(b);
people.add(c);
people.add(d);
for (People person : people) {
System.out.println(person.getName()+","+person.getAge());
}
}
}
四、Collections中的静态方法
Collections为针对集合操作的工具类
常用的静态方法:
方法 | 说明 |
---|---|
static < T> void sort(List< T> list, Comparator<? super T> c) | 根据比较器排序 |
static void reverse(List<?> list) | 反转顺序 |
static void shuffle(List<?> list) | 随机排列 |
对ArrayList进行排序时可选用list.sort(Comparator c)
或者Collections.sort(list,Comparator c)
----------------------------------------------------分隔线---------------------------------------------------