集合简介
数组也是集合,那么我们为什么还会引入集合?
这是因为数组有如下限制:
- 数组初始化后大小不可变;
- 数组只能按索引顺序存取。
因此,我们需要各种不同类型的集合类来处理不同的数据,例如:
- 可变大小的顺序链表;
- 保证无重复元素的集合;
Java标准库自带的java.util
包提供了集合类:Collection
,它是除Map
外所有其他集合类的根接口。Java的java.util
包主要提供了以下三种类型的集合:
List
:一种有序列表的集合,例如,按索引排列的Student
的List
;Set
:一种保证没有重复元素的集合,例如,所有无重复名称的Student
的Set
;Map
:一种通过键值(key-value)查找的映射表集合,例如,根据Student
的name
查找对应Student
的Map
。
使用list
list的基本使用
import java.util.ArrayList;
import java.util.List;
// 列表允许添加为空,允许添加重复的数据
public class Collection {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("apple");
list.add("pear");
//list.add("apple");
list.add(null);
//System.out.println(list.size());
String second = list.get(2);
System.out.println(second);
}
}
遍历list
// 遍历循环的三种方式
// 第一种方式(效率太低不推荐使用)
import java.util.List;
// List接口提供了of()方法,可以快速创建List 不能接收null值会报错
public class Collection{
public static void main(String[] args) {
List<String> list = List.of("apple","pear","banana");
for (int i=0;i<list.size();i++){
String s = list.get(i);
System.out.println(s);
}
}
}
// 第二种方法(使用迭代器遍历,速率提高,但写法复杂)
import java.util.Iterator;
import java.util.List;
public class Collection{
public static void main(String[] args) {
List<String> list = List.of("apple","pear","banana");
/*list.iterator() 生成迭代器对象
* it.hasNext() 判断是否有下一个元素
* it.next() 返回下一个元素
* */
for(Iterator<String> it=list.iterator();it.hasNext();){
String s = it.next();
System.out.println(s);
}
}
}
// 方式三(编译器会自动将for each变成迭代器)
import java.util.List;
public class Collection{
public static void main(String[] args) {
List<String> list = List.of("apple","pear","collection");
for (String s : list){
System.out.println(s);
}
}
}
List和Array转换
// List和Array转换的三种方式
// 第一种方式
// 通过调用toArray()方法直接返回一个object[]数组(会丢失类型信息,基本上不用)
import java.util.List;
public class Collection{
public static void main(String[] args) {
List<String> list = List.of("shuai","lili","tianmei");
Object[] array = list.toArray();
for (Object s : array){
System.out.println(s);
}
}
}
// 第二种方式
// 给toArray(T[])传入一个类型相同的Array
// 例如new Number[3]和new Integer[3]可以但是传入new String[3]
import java.util.List;
public class Collection{
public static void main(String[] args) {
List<Integer> list = List.of(12,34,56);
//Integer[] array = list.toArray(Integer[]::new);
Number[] array = list.toArray(new Number[3]);
for (Number n : array){
System.out.println(n);
}
}
}
// 第三种方式
// 给toArray(T[])传入一个类型相同的“恰好”大小的Array
import java.util.List;
public class Collection{
public static void main(String[] args) {
List<Integer> list = List.of(12,34,56);
//Integer[] array = list.toArray(new Integer[list.size()]);
// 可以简写为下面形式
Integer[] array = list.toArray(Integer[]::new);
for (Integer n : array){
System.out.println(n);
}
}
}
// 反过来,把Array变成List就简单多了 ,通过List.of(T...)方法最简单:
Integer[] array = {1,2,3};
List<Integer> list = List.of(array);
案例
// 问题一:从10~20遍历每个数字,然后从中任意删除一个数字,找到删除的数字(列表是有序的)
// 问题二:找到删除的数字(列表是无序的)
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Collection{
public static void main(String[] args) {
// 构造从start到end的序列
final int start = 10;
final int end = 20;
List<Integer> list = new ArrayList<>();
for (int i = start; i <= end; i++){
list.add(i);
}
// 洗牌算法shuffle可以随机交换List中的元素位置:
//Collections.shuffle(list);
// 随机删除List中的一个元素
int removed = list.remove((int) (Math.random()*list.size()));
int found = findMissingNumber(start,end,list);
System.out.println(list.toString());
System.out.println("missing number: " + found);
System.out.println(removed == found ? "测试成功":"测试失败");
}
static int findMissingNumber(int start,int end, List<Integer> list){
// 有序排列
int n = start;
for (int i:list){
if (i!=n)
break;
n++;
}
return n;
// 无序排列(使用作差法求解)
//int tatol = 0;
//for (int i=start;i<=end;i++){
// tatol = tatol +i;
//}
//for (Integer ns:list){
// tatol = tatol-ns;
//}
//return tatol;
}
}
编写equals方法
// 因为List内部并不是通过==判断两个元素是否相等,而是使用equals()方法判断两个元素是否相等
public class Main {
public static void main(String[] args) {
List<String> list = List.of("A", "B", "C");
System.out.println(list.contains(new String("C"))); // true
System.out.println(list.indexOf(new String("C"))); // 2
}
}
// 注意事项:对引用类型用Objects.equals()比较,对基本类型直接用==比较
// 编写equals
import java.util.List;
import java.util.Objects;
public class Collection{
public static void main(String[] args) {
List<Person> list = List.of(
new Person("xiao","ming",18),
new Person("xiao","haha",28),
new Person("shao","shuai",21)
);
boolean exist = list.contains(new Person("shao","shuai",21));
System.out.println(exist ? "测试成功":"测试失败");
}
}
class Person{
String firstName;
String lastName;
int age;
public Person(String firstName,String lastName,int age){
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public boolean equals(Object o) {
if (o instanceof Person) {
Person p = (Person) o;
return Objects.equals(this.firstName, p.firstName) && Objects.equals(this.lastName, p.lastName) && this.age == p.age;
}
return false;
}
}