集合简介

数组也是集合,那么我们为什么还会引入集合?

这是因为数组有如下限制:

  • 数组初始化后大小不可变;
  • 数组只能按索引顺序存取。

因此,我们需要各种不同类型的集合类来处理不同的数据,例如:

  • 可变大小的顺序链表;
  • 保证无重复元素的集合;

Java标准库自带的java.util包提供了集合类:Collection,它是除Map外所有其他集合类的根接口。Java的java.util包主要提供了以下三种类型的集合:

  • List:一种有序列表的集合,例如,按索引排列的StudentList
  • Set:一种保证没有重复元素的集合,例如,所有无重复名称的StudentSet
  • Map:一种通过键值(key-value)查找的映射表集合,例如,根据Studentname查找对应StudentMap

使用list

list的基本使用

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. // 列表允许添加为空,允许添加重复的数据
  4. public class Collection {
  5. public static void main(String[] args) {
  6. List<String> list = new ArrayList<>();
  7. list.add("apple");
  8. list.add("pear");
  9. //list.add("apple");
  10. list.add(null);
  11. //System.out.println(list.size());
  12. String second = list.get(2);
  13. System.out.println(second);
  14. }
  15. }

遍历list

  1. // 遍历循环的三种方式
  2. // 第一种方式(效率太低不推荐使用)
  3. import java.util.List;
  4. // List接口提供了of()方法,可以快速创建List 不能接收null值会报错
  5. public class Collection{
  6. public static void main(String[] args) {
  7. List<String> list = List.of("apple","pear","banana");
  8. for (int i=0;i<list.size();i++){
  9. String s = list.get(i);
  10. System.out.println(s);
  11. }
  12. }
  13. }
  14. // 第二种方法(使用迭代器遍历,速率提高,但写法复杂)
  15. import java.util.Iterator;
  16. import java.util.List;
  17. public class Collection{
  18. public static void main(String[] args) {
  19. List<String> list = List.of("apple","pear","banana");
  20. /*list.iterator() 生成迭代器对象
  21. * it.hasNext() 判断是否有下一个元素
  22. * it.next() 返回下一个元素
  23. * */
  24. for(Iterator<String> it=list.iterator();it.hasNext();){
  25. String s = it.next();
  26. System.out.println(s);
  27. }
  28. }
  29. }
  30. // 方式三(编译器会自动将for each变成迭代器)
  31. import java.util.List;
  32. public class Collection{
  33. public static void main(String[] args) {
  34. List<String> list = List.of("apple","pear","collection");
  35. for (String s : list){
  36. System.out.println(s);
  37. }
  38. }
  39. }

List和Array转换

  1. // List和Array转换的三种方式
  2. // 第一种方式
  3. // 通过调用toArray()方法直接返回一个object[]数组(会丢失类型信息,基本上不用)
  4. import java.util.List;
  5. public class Collection{
  6. public static void main(String[] args) {
  7. List<String> list = List.of("shuai","lili","tianmei");
  8. Object[] array = list.toArray();
  9. for (Object s : array){
  10. System.out.println(s);
  11. }
  12. }
  13. }
  14. // 第二种方式
  15. // 给toArray(T[])传入一个类型相同的Array
  16. // 例如new Number[3]和new Integer[3]可以但是传入new String[3]
  17. import java.util.List;
  18. public class Collection{
  19. public static void main(String[] args) {
  20. List<Integer> list = List.of(12,34,56);
  21. //Integer[] array = list.toArray(Integer[]::new);
  22. Number[] array = list.toArray(new Number[3]);
  23. for (Number n : array){
  24. System.out.println(n);
  25. }
  26. }
  27. }
  28. // 第三种方式
  29. // 给toArray(T[])传入一个类型相同的“恰好”大小的Array
  30. import java.util.List;
  31. public class Collection{
  32. public static void main(String[] args) {
  33. List<Integer> list = List.of(12,34,56);
  34. //Integer[] array = list.toArray(new Integer[list.size()]);
  35. // 可以简写为下面形式
  36. Integer[] array = list.toArray(Integer[]::new);
  37. for (Integer n : array){
  38. System.out.println(n);
  39. }
  40. }
  41. }
  42. // 反过来,把Array变成List就简单多了 ,通过List.of(T...)方法最简单:
  43. Integer[] array = {1,2,3};
  44. List<Integer> list = List.of(array);

案例

  1. // 问题一:从10~20遍历每个数字,然后从中任意删除一个数字,找到删除的数字(列表是有序的)
  2. // 问题二:找到删除的数字(列表是无序的)
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.List;
  6. public class Collection{
  7. public static void main(String[] args) {
  8. // 构造从start到end的序列
  9. final int start = 10;
  10. final int end = 20;
  11. List<Integer> list = new ArrayList<>();
  12. for (int i = start; i <= end; i++){
  13. list.add(i);
  14. }
  15. // 洗牌算法shuffle可以随机交换List中的元素位置:
  16. //Collections.shuffle(list);
  17. // 随机删除List中的一个元素
  18. int removed = list.remove((int) (Math.random()*list.size()));
  19. int found = findMissingNumber(start,end,list);
  20. System.out.println(list.toString());
  21. System.out.println("missing number: " + found);
  22. System.out.println(removed == found ? "测试成功":"测试失败");
  23. }
  24. static int findMissingNumber(int start,int end, List<Integer> list){
  25. // 有序排列
  26. int n = start;
  27. for (int i:list){
  28. if (i!=n)
  29. break;
  30. n++;
  31. }
  32. return n;
  33. // 无序排列(使用作差法求解)
  34. //int tatol = 0;
  35. //for (int i=start;i<=end;i++){
  36. // tatol = tatol +i;
  37. //}
  38. //for (Integer ns:list){
  39. // tatol = tatol-ns;
  40. //}
  41. //return tatol;
  42. }
  43. }

编写equals方法

  1. // 因为List内部并不是通过==判断两个元素是否相等,而是使用equals()方法判断两个元素是否相等
  2. public class Main {
  3. public static void main(String[] args) {
  4. List<String> list = List.of("A", "B", "C");
  5. System.out.println(list.contains(new String("C"))); // true
  6. System.out.println(list.indexOf(new String("C"))); // 2
  7. }
  8. }
  9. // 注意事项:对引用类型用Objects.equals()比较,对基本类型直接用==比较
  10. // 编写equals
  11. import java.util.List;
  12. import java.util.Objects;
  13. public class Collection{
  14. public static void main(String[] args) {
  15. List<Person> list = List.of(
  16. new Person("xiao","ming",18),
  17. new Person("xiao","haha",28),
  18. new Person("shao","shuai",21)
  19. );
  20. boolean exist = list.contains(new Person("shao","shuai",21));
  21. System.out.println(exist ? "测试成功":"测试失败");
  22. }
  23. }
  24. class Person{
  25. String firstName;
  26. String lastName;
  27. int age;
  28. public Person(String firstName,String lastName,int age){
  29. this.firstName = firstName;
  30. this.lastName = lastName;
  31. this.age = age;
  32. }
  33. public boolean equals(Object o) {
  34. if (o instanceof Person) {
  35. Person p = (Person) o;
  36. return Objects.equals(this.firstName, p.firstName) && Objects.equals(this.lastName, p.lastName) && this.age == p.age;
  37. }
  38. return false;
  39. }
  40. }