1 List
上篇我们介绍到Collection接口的使用之后,接下来我们看看它的子类都有哪些特点呢?
1.1 List接口介绍
List继承自Collection接口,是单例集合中最重要的分支之一,我们通常会将实现了List接口的对象称之为集合,在List集合中允许出现重复的元素,它是以线性的方式把元素存储起来,所以,我们可以通过索引来获取List集合中的元素,并且,List集合中的额元素允许重复,这个是非常重要的,另外,List集合还有一个特点就是元素有序,即元素的存入顺序和取出顺序一致。
List接口特点:
- 它是一个元素存取有序的集合。
- 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。
- 集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。
1.2 List接口中常用方法
List作为Collection的子接口,不但继承了Collection中的全部方法而且还增加了一些根据元素索引来操作集合的特有方法,如下:
- public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。
- public E get(int index) :返回集合中指定位置的元素。
- public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。
- public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
注意:List集合特有的方法都是跟索引相关
1.3 ArrayList集合
java.util.ArrayList 集合数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以 ArrayList 是最常用的集合。
许多程序员开发时非常随意地使用ArrayList完成任何需求,并不严谨,这种用法是不提倡的。我们用该根据业务需求来决定到底用哪一种集合类型!
ArrayList在上篇已经介绍过,这里都不多说了!
1.4 LinkedList集合
java.util.LinkedList 集合数据存储的结构是链表结构。方便元素添加、删除的集合。
实际开发中对一个集合元素的添加与删除经常涉及到首尾操作,而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。
LinkedList是List的子类,List中的方法LinkedList都是可以使用,这里就不做详细介绍,我们只需要了解LinkedList的特有方法即可。在开发时,LinkedList集合也可以作为堆栈,队列的结构使用。
案例介绍:
import java.util.LinkedList;
public class LinkedListTest {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("赵六");
list.addFirst("小波");
list.addLast("小多");
//pop,把第一个元素删除并返回这个元素
String pop = list.pop();
System.out.println(pop);
//push:在第一个元素中添加元素==》addList
list.push("小雅");
// for (String s : list) {
// System.out.println(s);
// }
System.out.println(list);
}
}
2 Collections类
2.1 Collections常用功能
java.utils.Collections 是集合工具类,用来对集合进行操作。
常用方法如下:
- public static void shuffle(List<?> list) :打乱集合顺序。
- public static void sort(List list) :将集合中元素按照默认规则排序。
- public static void sort(List list,Comparator<? super T> ) :将集合中元素按照指定规则排序。
代码演示:
public class CollectionsDemo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(100);
list.add(300);
list.add(200);
list.add(50);
//排序方法
Collections.sort(list);
System.out.println(list);
}
}
结果: [50,100, 200, 300]
2.2 Comparator比较器
2.3 可变参数
格式:
修饰符 返回值类型 方法名(参数类型... 形参名){ }
注意:
- 一个方法只能有一个可变参数
- 如果方法中有多个参数,可变参数要放到最后。
应用场景: Collections
下面是对比较器和可变参数的案例演示
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
* public static void shuffle(List<?> list) :打乱集合顺序。
* public static <T> void sort(List<T> list) :将集合中元素按照默认规则排序。
* public static <T> void sort(List<T> list,Comparator<? super T> ) :将集合中元素按照指定规则排序。
*/
public class CollectionsTest {
public static void main(String[] args) {
ArrayList<Integer>list = new ArrayList<>();
list.add(12);
list.add(32);
list.add(34);
list.add(52);
list.add(199);
//增加元素也可以用Collections,更简单
Collections.addAll(list,12,32,34,52,199);
//shuffle(List<?> list) :打乱集合顺序。
//Collections.shuffle(list);
//sort(List<T> list);,按照升序排列
//Collections.sort(list);
//sort(List<T> list,Comparator<? super T> ) :将集合中元素按照指定规则排序。
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
//o1-o2:升序排列
//o2-o2:降序排列
return o2-o1;
}
});
System.out.println(list);
System.out.println("-----------------------------");
//可变参数,注意:当固定参数与可变参数在一起时,可变参数必须放在最后面!!
int sum = method(2001,234,54,12,65);
System.out.println(sum);
}
private static int method(int s,int... arr) {
int num = 0;
for (int num1:arr) {
num += num1;
}
return num+s;
}
}
3 Set接口
java.util.Set 接口和 java.util.List 接口一样,同样继承自 Collection 接口,它与 Collection 接口中的方法基本一致,并没有对 Collection 接口进行功能上的扩充,只是比 Collection 接口更加严格了。与List 接口不同的是, Set 接口都会以某种规则保证存入的元素不出现重复。
Set 集合有多个子类,这里我们介绍其中的 java.util.HashSet 、java.util.LinkedHashSet 、 java.util.TreeSet 这三个集合。
3.1 HashSet集合介绍
- java.util.HashSet 是 Set 接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的(即存取顺序不能保证不一致)。
- HashSet 是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存储和查找性能。保证元素唯一性的方式依赖于: hashCode 与 equals 方法。
案例演示:
public class HashSetDemo {
public static void main(String[] args) {
//创建 Set集合
HashSet<String> set = new HashSet<String>();
//添加元素
set.add(new String("cba"));
set.add("abc");
set.add("bac");
set.add("cba");
//遍历
for (String name : set) {
System.out.println(name);
}
}
}
输出结果是:
cba
abc
bac
注意:根据结果我们发现字符串"cba"只存储了一个,也就是说重复的元素set集合不存储。
3.2 HashSet存储自定义类型元素
给HashSet中存放自定义类型元素时,需要重写对象中的hashCode和equals方法,建立自己的比较方式,才能保证HashSet集合中的对象唯一.
案例演示:
创建自定义Student类:
/**
* 定义学生类Student,属性:姓名、性别、年龄
*/
public class Student {
private String name;
private String sex;
private String age;
public Student(String name, String sex, String age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Objects.equals(name, student.name) &&
Objects.equals(sex, student.sex) &&
Objects.equals(age, student.age);
}
@Override
public int hashCode() {
return Objects.hash(name, sex, age);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age='" + age + '\'' +
'}';
}
}
创建测试类:
/**
* 定义一个存储Student类型的HashSet集合
* 创建以下三个Student对象
* 张三,男,20
* 李四,女,21
* 张三,男,20
* 将上述三个对象存储到Set集合中
* 使用增强for遍历集合,获取每个Student对象,并打印属性值;
* 请实现集合中不能存储姓名年龄相同的元素
*/
public class Test {
public static void main(String[] args) {
//将上述三个对象存储到Set集合中
HashSet<Student> students = new HashSet<>();
Student student1 = new Student("张三", "男", "20");
Student student2 = new Student("李四", "女", "21");
Student student3 = new Student("张三", "男", "20");
students.add(student1);
students.add(student2);
students.add(student3);
//使用增强for遍历集合,获取每个Student对象,并打印属性值;
for (Student student : students) {
System.out.println(student);
}
System.out.println("--------------------------------------------");
//请实现集合中不能存储姓名年龄相同的元素
HashSet<Student> hashSet = new HashSet<Student>();
hashSet.add(new Student("张三", "男", "20"));
hashSet.add(new Student("李四", "女", "21"));
hashSet.add(new Student("张三", "男", "20"));
for (Student stu2 : hashSet) {
System.out.println(stu2.getName()+stu2.getAge());
}
}
}
3.3 LinkedHashSet
我们知道HashSet保证元素唯一,可是元素存放进去是没有顺序的在HashSet下面有一个子类 java.util.LinkedHashSet ,它是链表和哈希表组合的一个数据存储结构。
案例演示:
/**
* 请按以下要求顺序编码:
* 定义一个可以存储“整数”的LinkedHashSet对象
* 存储以下整数
* 20,30,50,10,30,20
* 打印集合大小。为什么跟存入的数量不一致?
* 使用增强for遍历集合,打印大于25的元素
*/
public class Demo03 {
public static void main(String[] args) {
LinkedHashSet<Integer> integers = new LinkedHashSet<>();
Collections.addAll(integers,20,30,50,10,30,20);
//LinkedHashSet是HashSet的子类,元素不能重复,但是LinkedHashSet是有序的
System.out.println(integers);
//打印大于25的元素
for (Integer integer : integers) {
if(integer>25){
System.out.println(integer);
}
}
}
}
3.3 TreeSet集合
3.3.1 特点:
- 元素唯一
- 元素没有索引
- 使用元素的自然顺序对元素进行排序,或者根据创建 TreeSet 时提供的 Comparator 比较器 进行排序,具体取决于使用的构造方法:
public TreeSet(): 根据其元素的自然排序进行排序
public TreeSet(Comparator<E> comparator): 根据指定的比较器进行排序
3.3.2 案例演示:
/**
* 请按以下要求顺序编码:
* 定义一个可以存储“整数”的TreeSet对象
* 存储以下整数
* 30,20,50,10,30,20
* 打印集合大小。为什么跟存入的数量不一致?
* 遍历集合,打印大于25的元素
*/
public class Demo04 {
public static void main(String[] args) {
TreeSet<Integer> integers = new TreeSet<>();
Collections.addAll(integers,30,20,50,10,30,20);
//TreeSet可以自动升序,但元素也不能重复
System.out.println(integers.size());
for (Integer integer : integers) {
if(integer > 25){
System.out.println(integer);
}
}
}
}