3.java基础回顾集合2
1.List接口
特点:
- 继承自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):用指定元素替换集合中指定位置的元素,返回值为被替换的元素
注意:
操作索引的时候,一定要防止索引越界异常
2.ArrayList集合:多线程
特点:查询快,增删慢,每增加一个元素底层使用的是数组的拷贝,将数组整个拷贝所以增删慢
3.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():与removeFirst方法相同
- public void push(E e):与addFirst方法相同
- public boolean isEmpty():判断列表是否为空
4.Vector集合:单线程
特点:
- 最早期的类
- 单线程速度慢
- 与ArrayList相同,底层都是数组实现,基本被ArrayList代替了
- 使用Enumeration接口实现Iterator接口的相同的遍历功能,由于当时没有Iterator接口
5.Set接口
特点:
- 继承Collection接口
- 不允许存储相同元素
- 没有索引,也没有带索引的方法,同时也不能使用普通for循环遍历,但可以用foreach循环遍历
6.HashSet集合
特点:
- 实现了Set接口
- 拥有和Set接口一样的特点
- 底层是一个哈希表结构(查询的速度非常快)
注:
- 哈希值:是一个十进制整数,有系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到的地址,不是数据实际存储的物理地址)。
- 在Object类中有一个方法,可以获取对象的哈希值:
- int hashcode():返回该对象的哈希码值
- hashcode方法的源码:public native int hashcode(); 其中native表示该方法调用本地操作系统的方法。
HashSet集合存储结构(哈希表)
- JDK1.8之前:数组+链表
- JDK1.8之后:数组+链表/红黑树,数组相同位置存储哈希值相同元素生成一个链表,当链表长度大于8时,变为红黑树存储,用来提高查询速度。
HashSet存储自定义类型元素:必须重写hashcode和equals方法
Person类中重写hashcode和equals方法
1 package day01; 2 3 import java.util.Objects; 4 5 /** 6 * @author USTC_WZH 7 * @create 2019-12-29 22:02 8 */ 9 public class Person { 10 11 private String name; 12 private int age; 13 14 public Person(String name, int age) { 15 this.name = name; 16 this.age = age; 17 } 18 19 @Override 20 public boolean equals(Object o) { 21 if (this == o) return true; 22 if (o == null || getClass() != o.getClass()) return false; 23 Person person = (Person) o; 24 return age == person.age && 25 Objects.equals(name, person.name); 26 } 27 28 @Override 29 public int hashCode() { 30 return Objects.hash(name, age); 31 } 32 33 @Override 34 public String toString() { 35 return "Person{" + 36 "name='" + name + '\'' + 37 ", age=" + age + 38 '}'; 39 } 40 41 public String getName() { 42 return name; 43 } 44 45 public void setName(String name) { 46 this.name = name; 47 } 48 49 public int getAge() { 50 return age; 51 } 52 53 public void setAge(int age) { 54 this.age = age; 55 } 56 }
1 public class demo7 { 2 3 public static void main(String[] args) { 4 5 Person p1 = new Person("wzl",23); 6 Person p2 = new Person("wzl", 23); 7 Person p3 = new Person("wzh",24); 8 9 HashSet<Person> hashSet = new HashSet<>(); 10 hashSet.add(p1); 11 hashSet.add(p2); 12 hashSet.add(p3); 13 14 for (Person p :hashSet 15 ) { 16 System.out.println(p.getName() + ":" + p.getAge()); 17 } 18 } 19 }
7.LinkedHashSet类
特点:
- 继承自HashSet类
- 底层是一个哈希表(数组+链表/红黑树)+链表(用于记录元素存储顺序),保证元素有序
1 public static void main(String[] args) { 2 HashSet<String> hashSet = new HashSet<>(); 3 4 hashSet.add("www"); 5 hashSet.add("abc"); 6 hashSet.add("test"); 7 8 System.out.println(hashSet); //[abc, test, www] 9 10 LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>(); 11 12 linkedHashSet.add("www"); 13 linkedHashSet.add("abc"); 14 linkedHashSet.add("test"); 15 16 System.out.println(linkedHashSet); //[www, abc, test] 17 }
补充:
可变参数:
- JDK1.5之后才出现的新特性
- 当方法的参数列表数据类型已经确定,但参数个数不确定,就可以使用可变参数
- 格式:修饰符 返回值类型 方法名(数据类型... 变量名)
- 可变参数的原理:底层创建数组来存储这些参数,参数数量任意
注意事项:
- 一个方法的可变参数只能有一个
- 当方法中有多个参数,可变参数必须为最后一个参数
终极写法是传入参数为Object... objects
1 public class demo01 { 2 3 public static void printArray(int... arr) { 4 System.out.println("数组元素有:" + arr.length + "个"); 5 for (int i : arr 6 ) { 7 System.out.println(i); 8 } 9 } 10 11 public static void printAll(Object... objects) { 12 System.out.println("数组元素有:" + objects.length + "个"); 13 for (Object i : objects 14 ) { 15 System.out.println(i); 16 } 17 } 18 19 public static void main(String[] args) { 20 21 printArray(1, 2, 3, 4, 5, 6); 22 printAll(6,5,4,3,2,1); 23 } 24 }
8.Collections集合工具类
定义在java.utils.Collections中
常用方法:
- public static<T> boolean addAll(Collection<T> c, T... elements):往集合中添加元素
- pubic static void shuffle<List<?> list):打乱集合中元素顺序
- public static <T> void sort(List<T> list):将集合元素按照默认顺序排序(升序)
- public static <T> void sort(List<T> list, Comparator<? super T>):将集合元素按照指定顺序排序
注意:
- 自定义类型如果使用sort方法进行排序,必须实现Comparable接口,重写接口中的方法compareTo来定义排序规则
- compareTo排序规则是:按照属性a进行排序
- this对象.属性a - 参数对象.属性a:返回升序
- 参数对象.属性a - this对象.属性a:返回降序
Person类:
1 package day02; 2 3 import java.util.Objects; 4 5 /** 6 * @author USTC_WZH 7 * @create 2019-12-29 22:02 8 */ 9 public class Person implements Comparable<Person>{ 10 11 private String name; 12 private int age; 13 14 public Person(String name, int age) { 15 this.name = name; 16 this.age = age; 17 } 18 19 @Override 20 public boolean equals(Object o) { 21 if (this == o) return true; 22 if (o == null || getClass() != o.getClass()) return false; 23 Person person = (Person) o; 24 return age == person.age && 25 Objects.equals(name, person.name); 26 } 27 28 @Override 29 public int hashCode() { 30 return Objects.hash(name, age); 31 } 32 33 @Override 34 public String toString() { 35 return "Person{" + 36 "name='" + name + '\'' + 37 ", age=" + age + 38 '}'; 39 } 40 41 public String getName() { 42 return name; 43 } 44 45 public void setName(String name) { 46 this.name = name; 47 } 48 49 public int getAge() { 50 return age; 51 } 52 53 public void setAge(int age) { 54 this.age = age; 55 } 56 57 @Override 58 public int compareTo(Person o) { 59 return o.getAge() - this.getAge(); //降序 60 } 61 }
1 public class demo02 { 2 3 public static void main(String[] args) { 4 5 ArrayList<String> arrayList = new ArrayList<>(); 6 7 //向集合中添加元素 8 Collections.addAll(arrayList, "bbb", "ccc", "aaa", "ddd"); 9 10 //原始顺序 11 System.out.println(arrayList); //[bbb, ccc, aaa, ddd] 12 13 //默认排序顺序(升序) 14 Collections.sort(arrayList); 15 System.out.println(arrayList); //[aaa, bbb, ccc, ddd] 16 17 //打乱顺序 18 Collections.shuffle(arrayList); 19 System.out.println(arrayList); //[ccc, bbb, ddd, aaa] 20 Collections.shuffle(arrayList); 21 System.out.println(arrayList); //[aaa, bbb, ddd, ccc] 22 23 ArrayList<Person> arr = new ArrayList<>(); 24 arr.add(new Person("wzl",23)); 25 arr.add(new Person("wxl",22)); 26 arr.add(new Person("wzh",24)); 27 arr.add(new Person("aaa", 24)); 28 29 30 //降序,使用定义在Person类中的重写方法compareTo 31 Collections.sort(arr); 32 System.out.println(arr); 33 34 //降序,使用函数式接口 35 Collections.sort(arr,Comparator.comparingInt(Person::getAge).reversed()); 36 System.out.println(arr); 37 38 //升序,使用Lambda表达式 39 Collections.sort(arr,(Person a,Person b)->{return a.getAge() - b.getAge();}); 40 System.out.println(arr); 41 42 //升序,使用函数式接口 43 Collections.sort(arr, Comparator.comparingInt(Person::getAge)); 44 System.out.println(arr); 45 46 //多个属性排序:年龄从大到小,姓名字典序排列 47 Collections.sort(arr,(Person a, Person b)->{ 48 49 //首先按照年龄降序 50 int result = b.getAge() - a.getAge(); 51 52 //如果年龄相等在按照姓名字典序排列 53 if(result == 0){ 54 result = a.getName().compareTo(b.getName()); 55 } 56 return result; 57 58 }); 59 System.out.println(arr); 60 61 } 62 }