Java大数据开发和安全开发
- (一)Java的集合进阶
- 1.1 集合体系结构
- 1.2 Collection集合
- 1.2.1 Collection集合包含哪些接口和实现类
- 1.2.2 Collection集合特点
- 1.2.3 为啥要先学Collection的常用方法?
- 1.2.4 Collection集合的遍历
- 1.2.4.1 迭代器
- 1.2.4.1.1 迭代器概述
- 1.2.4.1.2 Collection集合获取迭代器的方法
- 1.2.4.2 增强for
- 1.2.4.3 Lambvda表达式
- 1.2.4.3.1 Lambda表达式遍历集合
- 1.2.5 Collection集合案例演示
- 1.3 List集合
- 1.3.1 List集合的特有方法
- 1.3.2 List集合的遍历
- 1.3.3 Arraylist集合
- 1.3.4 Linkedlist集合
- 1.3.4.1 单链表
- 1.3.4.2 双链表
- 1.3.4.3 LinkedList特有方法
- 1.4 Set集合
- 1.4.1 Hashset集合的底层原理
- 1.4.1.1 哈希值的概念
- 1.4.1.2 Hashset集合的底层原理
- 1.4.1.1.1 JDK8之前,哈希表=`数组+链表 `
- 1.4.1.1.2 JDK8开始,哈希表=`数组+链表+红黑树`
- 1.4.1.1.3 数据结构
- 1.4.1.1.3.1 普通二叉树
- 1.4.1.1.3.2 二叉查找树
- 1.4.1.1.3.3 平衡二叉树
- 1.4.1.1.3.4 自平衡的二叉树 红黑树
- 1.4.1.3 深入理解Hashset集合去重复的机制。
- 1.4.2 LinkedHashSet集合
- 1.4.2 TreeSet集合
- 1.4.2.1 自定义排序规则
- 1.4.2.1.1 方式一
- 1.4.2.1.2 方式二
- 1.5 Collection集合的使用场景
(一)Java的集合进阶
1.1 集合体系结构
为了应对不同的场景需要,所以提供很多集合,总体来说分成单列集合和双列集合
1.2 Collection集合
1.2.1 Collection集合包含哪些接口和实现类
- 包含list接口和set接口
- 包含Arraylist linkedlist hashset treeset实现类
1.2.2 Collection集合特点
- List系列集合:
添加的元素是有序、可重复、有索引
。- ArrayList、LinekdList:有序、可重复、有索引。
- set系列集合:
添加的元素是无序、不重复、无索引
。- Hashset:无序、不重复、无索引:
- LinkedHashset:
有序
、不重复、无索引。 - TreeSet:
按照大小默认升序排序
、不重复、无索引。
1.2.3 为啥要先学Collection的常用方法?
- Collection是单列集合的祖宗,它规定的方法(功能)是全部单列集合都会继承的。
- 以下是Collection的常用方法代码示例
package com.qianxin.jihekuangjia;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class Test1 {
public static void main(String[] args) {
Collection<String> c= new ArrayList<>();// 多态写法
//1.public boolean add(E e):添加元素,添加成功返回true。
c.add("java1");
c.add("java1");
c.add("java2");
c.add("java2");
c.add("java3");
System.out.println(c);
// 2.public void clear():清空集合的元素,
c.clear();
System.out.println(c);
//3.public boolean isEmpty():判断集合是否为空 是空返回true,反之
System.out.println(c.isEmpty());//true
// 4.public int size():获取集合的大小。
System.out.println(c.size());
//5.public boolean contains(0bject obj):判断集合中是否包含某个元素
System.out.println(c.contains("java1"));// true
System.out.println(c.contains("Java1"));// false
//6.public boolean remove(E e):删除某个元素:如果有多个重复元素默认删除前面的第一个!
System.out.println(c.remove( "java1"));
System.out.println(c);
//7.public 0bject[]toArray():把集合转换成数组
Object[] arr = c.toArray();
System.out.println(Arrays.toString(arr));
String[]arr2 =c.toArray(new String[c.size()]);
System.out.println(Arrays.toString(arr2));
// 把一个集合的全部数据倒入到另一个集合中去。
Collection<String>c1 = new ArrayList<>();c1.add("java1");
c1.add("java2");
Collection<String>c2 =new ArrayList<>();
c2.add("java3");
c2.add("java4");
c1.addAll(c2);//就是把c2集合的全部数据倒入到c1集合中去。
System.out.println(c1);
}
}
1.2.4 Collection集合的遍历
1.2.4.1 迭代器
1.2.4.1.1 迭代器概述
迭代器是用来遍历集合的专用方式(数组没有迭代器),在ava中迭代器的代表是Iterator。
1.2.4.1.2 Collection集合获取迭代器的方法
Collection获取迭代器的方法
Iterator迭代器中的常用方法
Iterator迭代器的使用
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
/**大
目标:Collection集合的遍历方式一:使迭代器Iterator遍历
**/
public class Test {
public static void main(String[] args) {
Collection<String> c=new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("索素");
c.add("灭绝");
System.out.println(c);
//c=[赵敏,小昭,素素,灭绝]
//使用迭代器遍历集合
// 使用迭代器遍历集合
// 1、从集合对象中获取迭代器对象。
Iterator<String> it = c.iterator();
System.out.println(it.next());
System.out.println(it.next());
System.out.println(it.next());
System.out.println(it.next());
System.out.println(it.next());// 出现异常的
// 2、我们应该使用循环结合迭代器遍历集合。
while(it.hasNext()) {
String ele = it.next();
System.out.println(ele);
}
}
}
[赵敏, 小昭, 索素, 灭绝]
赵敏
小昭
索素
灭绝
1.2.4.2 增强for
- 增强for可以用来遍历集合或者数组。
- 增强for遍历集合,本质就是迭代器遍历集合的简化写法。
增强for遍历集合代码示例
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
Collection<String> c=new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("索素");
c.add("灭绝");
System.out.println(c);
//c=[赵敏,小昭,素素,灭绝]
// 使用增强for遍历集合或者数组、ele这个可以随意写 类似python的for iter in list ele等同于iter
for(String ele :c){
System.out.println(ele);
}
String[] names ={"迪丽热巴","古力娜扎","稀奇哈哈"};
for(String name :names) {
System.out.println(name);
}
}
}
1.2.4.3 Lambvda表达式
1.2.4.3.1 Lambda表达式遍历集合
得益于JDK 8开始的新技术Lambda表达式,提供了一种更简单、更直接的方式来遍历集合。
- 需要使用Collection的如下方法来完成
Lambda表达式遍历集合代码示例
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
public class Test {
public static void main(String[] args) {
Collection<String> c=new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("索素");
c.add("灭绝");
System.out.println(c);
//c=[赵敏,小昭,素素,灭绝]
// default void forEach(Consumer<? super T> action):结合Lambda表达式遍历集合
c.forEach(new Consumer<String>(){
@Override
public void accept(String s) {
System.out.println(s);
}
});
}
}
[赵敏, 小昭, 索素, 灭绝]
赵敏
小昭
索素
灭绝
但是上面代码还可以进行如下简化过程
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
public class Test {
public static void main(String[] args) {
Collection<String> c=new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("索素");
c.add("灭绝");
System.out.println(c);
//c=[赵敏,小昭,素素,灭绝]
// default void forEach(Consumer<? super T> action):结合Lambda表达式遍历集合
c.forEach(new Consumer<String>(){
@Override
public void accept(String s) {
System.out.println(s);
}
});
c.forEach((String s)->{
System.out.println(s);
});
c.forEach(s->{
System.out.println(s);
});
c.forEach(s -> System.out.println(s));
//最终简化的代码如下
c.forEach(System.out::println);
}
}
最终代码变成
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
public class Test {
public static void main(String[] args) {
Collection<String> c=new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("索素");
c.add("灭绝");
System.out.println(c);
//c=[赵敏,小昭,素素,灭绝]
// default void forEach(Consumer<? super T> action):结合Lambda表达式遍历集合
//最终简化的代码如下
c.forEach(System.out::println);
}
}
1.2.5 Collection集合案例演示
需求
- 展示多部电影信息。
分析
-
每部电影都是一个对象,多部电影要使用集合装起来,
-
遍历集合中的3个电影对象,输出每部电影的详情信息,
电影循环展示代码示例
package com.qianxin.jihekuangjia;
import java.util.ArrayList;
import java.util.Collection;
public class SystemDemo {
public static void main(String[] args) {
Collection<Movie> movies = new ArrayList<>();
movies.add(new Movie("《肖生克的救赎》",9.7,"罗宾斯"));
movies.add(new Movie("《霸王别姬》",9.6,"张国荣、张丰毅"));
movies.add(new Movie("《阿甘正传》",9.5,"汤姆.汉克斯"));
System.out.println(movies); //输出的是对象的内存地址 需要改写toString方法
for(Movie movie :movies) {
System.out.println("电影名:" + movie.getName());
System.out.println("评分:" + movie.getScore());
System.out.println("主演:" + movie.getAcotr());
System.out.println("------------------------------------");
}
}
}
public class Movie {
private String name;
private double score;
private String acotr;
public Movie() {
}
public Movie(String name, double score, String acotr) {
this.name = name;
this.score = score;
this.acotr = acotr;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public String getAcotr() {
return acotr;
}
public void setAcotr(String acotr) {
this.acotr = acotr;
}
@Override
public String toString() {
return "Movie{" +
"name='" + name + '\'' +
", score=" + score +
", acotr='" + acotr + '\'' +
'}';
}
}
1.3 List集合
1.3.1 List集合的特有方法
List集合因为支持索引,所以多了很多与索引相关的方法,当然,Collection的功能List也都继承了。
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
//1.创建一个ArrayList集合对象(有序、可重复、有索引)
List<String> list = new ArrayList<>();// 一行经典代码
list.add("蜘蛛精");
list.add("至尊宝");
list.add("至尊宝");
list.add("牛夫人");
System.out.println(list);//[蜘蛛精,至尊宝,至尊宝,牛夫人]
//2.public void add(int index,E element):在某个索引位置插入元素。
list.add( 2, "紫霞仙子");
System.out.println(list);
// 3.public E remove(int index):根据索引删除元素,返回被删除元素
System.out.println(list.remove(2));
System.out.println(list);
// 4.public E get(int index):返回集合中指定位置的元素。
System.out.println(list.get(3));
// 5.public E set(int index,E element): 修改索引位置处的元素,修改成功后,会返回原来的数据
System.out.println(list.set(3,"牛魔王"));
System.out.println(list);
}
}
1.3.2 List集合的遍历
- for循环(因为List集合有索引)
- 迭代器
- 增强for循环
- Lambda表达式
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("糖宝宝");
list.add("蜘蛛精");
list.add("至尊宝");
//for循环
for (int i = 0; i < list.size(); i++) {
String name = list.get(i);
System.out.println(name);
}
//迭代器
Iterator<String> it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
//lambda表达式
list.forEach(System.out::println);
//增加for
for (String s : list) {
System.out.println(s);
}
}
}
1.3.3 Arraylist集合
- ArrayList:有序,可重复,有索引。
- LinkedList:有序,可重复,有索引。
两者的区别
- 底层采用的数据结构不同,应用场景不同
- 数据结构指的是存储、组织数据的方式
ArrayList集合的底层原理
- 基于数组实现的。
- 查询速度快(注意:是根据索引查询数据快):查询数据通过地址值和索引定位,查询任意数据耗时相同。
- 删除效率低:可能需要把后面很多的数据进行前移
- 添加效率极低:可能需要把后面很多的数据后移,再添加元素;或者也可能需要进行数组的扩容。
利用无参构造器创建的集合,会在底层创建一个默认长度为0的数组
添加第一个元素时,底层会创建一个新的长度为10的数组
存满时,会扩容1.5倍
ArrayList集合适合的应用场景
1、ArrayList适合:根据索引查询数据比如根据随机索引取数据(高效)!或者数据量不是很大时!
2、ArrayList不适合:数据量大的同时,又要频繁的进行增删操作!
1.3.4 Linkedlist集合
LinkedList集合的底层原理
- 基于双链表实现的
1.3.4.1 单链表
- 链表的特点1: 查询慢,无论查询哪个数据都要从头开始找
- 链表的特点2: 链表增删相对快
- 链表中的结点是独立的对象,在内存中是不连续的,每个结点包含数据值和下一个结点的地址
1.3.4.2 双链表
- 特点:查询慢,增删相对较快,但对首尾元素进行增删改查的速度是极快的。
1.3.4.3 LinkedList特有方法
LinkedList新增了:很多首尾操作的特有方法。
LinkedList的应用场景之一:可以用来设计队列
- 是在首尾增删元素,用Linkecllist来实现很合适!
import java.util.LinkedList;
public class LinkedListTest {
public static void main(String[] args) {
// 1、创建一个队列。
LinkedList<String> queue = new LinkedList<>();
// 入队
queue.addLast("第1号人");
queue.addLast("第2号人");
queue.addLast("第3号人");
queue.addLast("第4号人");
System.out.println(queue);
// 出队
System.out.println(queue.removeFirst());
System.out.println(queue.removeFirst());
System.out.println(queue.removeFirst());
System.out.println(queue);
}
}
[第1号人, 第2号人, 第3号人, 第4号人]
第1号人
第2号人
第3号人
[第4号人]
LinkedList的应用场景之一:可以用来设计栈
- 只是在首部增删元素,用LinkeclList来实现很合适!
import java.util.LinkedList;
public class LinkedListTest {
public static void main(String[] args) {
// 2、创建一个栈对象。
LinkedList<String> stack = new LinkedList<>();
// 压栈
stack.addFirst("第1颗子弹");
stack.addFirst("第2颗子弹");
stack.addFirst("第3颗子弹");
stack.addFirst("第4颗子弹");
System.out.println(stack);
// 出栈
System.out.println(stack.removeFirst());
System.out.println(stack.removeFirst());
System.out.println(stack);
}
}
[第4颗子弹, 第3颗子弹, 第2颗子弹, 第1颗子弹]
第4颗子弹
第3颗子弹
[第2颗子弹, 第1颗子弹]
addFirst 等价于 push压栈
removeFirst 等价于 pop出栈
import java.util.LinkedList;
public class LinkedListTest {
public static void main(String[] args) {
// 2、创建一个栈对象。
LinkedList<String> stack = new LinkedList<>();
// 压栈
stack.push("第1颗子弹");
stack.push("第2颗子弹");
stack.push("第3颗子弹");
stack.push("第4颗子弹");
System.out.println(stack);
// 出栈
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack);
}
}
[第4颗子弹, 第3颗子弹, 第2颗子弹, 第1颗子弹]
第4颗子弹
第3颗子弹
[第2颗子弹, 第1颗子弹]
1.4 Set集合
Set系列集合特点:无序:添加数据的顺序和获取出的数据顺序不一致; 无索引; 不重复:
- Hashset:无序、不重复、无索引。
- LinkedHashSet:有序、不重复、无索引。
- Treeset:排序、不重复、无索引。
import java.util.HashSet;
import java.util.Set;
public class SetTest {
public static void main(String[] args) {
//1、创建一个Set集合的对象
Set<Integer> set = new HashSet<>();// 创建了一个HashSet的集合对象。一行经典代码 无序不重复 无索引
set.add(666);
set.add(555);
set.add(555);
set.add(888);
set.add(888);
set.add(777);
set.add(777);
System.out.println(set);
}
}
[888, 777, 666, 555]
import java.util.LinkedHashSet;
import java.util.Set;
public class SetTest {
public static void main(String[] args) {
//1、创建一个Set集合的对象
Set<Integer> set = new LinkedHashSet<>();//有序 不重复 无索引
set.add(666);
set.add(555);
set.add(555);
set.add(888);
set.add(888);
set.add(777);
set.add(777);
System.out.println(set);
}
}
[666, 555, 888, 777]
import java.util.Set;
import java.util.TreeSet;
public class SetTest {
public static void main(String[] args) {
//1、创建一个Set集合的对象
Set<Integer>set=new TreeSet<>();// 可排序(升序)不重复 无索引
set.add(666);
set.add(555);
set.add(555);
set.add(888);
set.add(888);
set.add(777);
set.add(777);
System.out.println(set);
}
}
[555, 666, 777, 888]
注意:
Set要用到的常用方法,基本上就是collection提供的!!
自己几乎没有额外新增一些常用功能!
1.4.1 Hashset集合的底层原理
1、为什么添加的元素无序、不重复、无索引?
2、增删改查数据有什么特点,适合什么场景?
1.4.1.1 哈希值的概念
- 就是一个int类型的数值,Java中每个对象都有一个哈希值。
- Java中的所有对象,都可以调用0bejct类提供的hashCode方法,返回该对象自己的哈希值。
- public int hashCode():返回对象的哈希码值。
对象哈希值的特点
- 同一个对象多次调用hashcode()方法返回的哈希值是相同的。
- 不同的对象,它们的哈希值一般不相同,但也有可能会相同(哈希碰撞),极少数会相同
public class Student {
private String name;
private int age;
private double height;
public Student() {
}
public Student(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
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;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
}
public class SetTest1 {
public static void main(String[] args) {
Student s1 = new Student( "蜘蛛精",25,169.5);
Student s2 =new Student( "紫霞",22,166.5);
System.out.println(s1.hashCode());
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
String str1 = new String( "abc");
String str2 = new String( "acD");
System.out.println(str1.hashCode());
System.out.println(str2.hashCode());
}
}
1163157884
1163157884
1956725890
96354
96354
1.4.1.2 Hashset集合的底层原理
- 基于
哈希表
实现。 - 哈希表是一种增删改查数据,性能都较好的数据结构
哈希表
- JDK8之前,哈希表=
数组+链表
- JDK8开始,哈希表=
数组+链表+红黑树
1.4.1.1.1 JDK8之前,哈希表=数组+链表
- hashSet在第一次添加数据时会创建一个默认长度16的数组,默认加载因子为0.75,数组名table
假如添加的元素是166 余数是1 那就放在1的位置 如果还有余数是1的就挂在166元素的下面
这就是为什么hashset添加的元素无序 不重复、无索引的原因
哈希表是一种增删改查数据性能都较好的结构
1、如果数组快占满了,会出什么问题?该咋办?
链表会过长,导致查询性能降低
扩容
1.4.1.1.2 JDK8开始,哈希表=数组+链表+红黑树
1.4.1.1.3 数据结构
1.4.1.1.3.1 普通二叉树
一个节点包括父节点地址 -》值-》左子节点地址-》右子节点地址
普通二叉树
没有意义 但是二叉查找树遵循二分法
1.4.1.1.3.2 二叉查找树
存在的问题:当数据已经是排好序的,导致查询的性能与单链表一样,查询速度变慢!
1.4.1.1.3.3 平衡二叉树
1.4.1.1.3.4 自平衡的二叉树 红黑树
1.4.1.3 深入理解Hashset集合去重复的机制。
Hashset集合默认不能对内容一样的两个不同对象去重复!
比如内容一样的两个学生对象存入到HashSet集合中去,Hashset集合是不能去重复的!
import java.util.HashSet;
import java.util.Set;
public class SetTest1 {
public static void main(String[] args) {
Set<Student> students =new HashSet<>();
Student s1 = new Student("至尊宝",28,169.6);
Student s2 = new Student("蜘蛛精",23,169.6);
Student s3 = new Student("蜘蛛精",23,169.6);
Student s4=new Student( "牛魔王",48,169.6);
students.add(s1);
students.add(s2);
students.add(s3);
students.add(s4);
System.out.println(students);
}
}
1.4.2 LinkedHashSet集合
LinkedHashset:有序、不重复、无索引
import java.util.LinkedHashSet;
import java.util.Set;
public class SetTest {
public static void main(String[] args) {
//1、创建一个Set集合的对象
Set<Integer> set = new LinkedHashSet<>();//有序 不重复 无索引
set.add(666);
set.add(555);
set.add(555);
set.add(888);
set.add(888);
set.add(777);
set.add(777);
System.out.println(set);
}
}
[666,555,888,777]
LinkedHashset底层原理
- 依然是基于哈希表(数组、链表、红黑树)实现的。
- 但是,它的每个元素都额外的多了一个双链表的机制记录它前后元素的位置。
假如元素的hash求余得到的是8,那么这个元素将放在下标为八的位置
1.4.2 TreeSet集合
- 特点:不重复、无索引 可排序
- 默认升序排序按照元素的大小,由小到大排序)
- 底层是基于红黑树实现的排序。
import java.util.Set;
import java.util.TreeSet;
public class SetTest1 {
public static void main(String[] args) {
Set<Integer>set1 = new TreeSet<>();
set1.add(6);
set1.add(5);
set1.add(5);
set1.add(7);
System.out.println(set1);
}
}
[5, 6, 7]
注意:
对于数值类型:Integer,Double,默认按照数值本身的大小进行升序排序
对于字符串类型:默认按照首字符的编号升序排序。
对于自定义类型如Student对象,Treeset默认是无法直接排序的,
TreeSet是一定会给集合排序的 不知道怎么排序的就会直接报错
import java.util.Set;
import java.util.TreeSet;
public class SetTest1 {
public static void main(String[] args) {
Set<Student> students =new TreeSet<>();
Student s1 = new Student("至尊宝",28,169.6);
Student s2 = new Student("蜘蛛精",23,169.6);
Student s3 = new Student("蜘蛛精",23,169.6);
Student s4=new Student( "牛魔王",48,169.6);
students.add(s1);
students.add(s2);
students.add(s3);
students.add(s4);
System.out.println(students);
}
}
1.4.2.1 自定义排序规则
TreeSet集合存储自定义类型的对象时,必须指定排序规则,支持如下两种方式来指定比较规则。
1.4.2.1.1 方式一
让自定义的类(如学生类)实现Comparable接口,重写里面的compareTo方法来指定比较规则。
public class Student implements Comparable<Student>{
private String name;
private int age;
private double height;
@Override
public int compareTo(Student o) {
// 如果认为左边对象大于右边对象返回正整数
// 如果认为左边对象小于右边对象返回负整数
// 如果认为左边对象等于右边对象返回0
// 需求:按照年龄升序排序、
return this.age-o.age;
}
public Student() {
}
public Student(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
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;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
}
import java.util.Set;
import java.util.TreeSet;
public class SetTest1 {
public static void main(String[] args) {
Set<Student> students =new TreeSet<>();
Student s1 = new Student("至尊宝",28,169.6);
Student s2 = new Student("蜘蛛精",23,169.6);
Student s3 = new Student("蜘蛛精",23,169.6);
Student s4=new Student( "牛魔王",48,169.6);
students.add(s1);
students.add(s2);
students.add(s3);
students.add(s4);
System.out.println(students);
}
}
按照年龄升序排列
[Student{name='蜘蛛精', age=23, height=169.6}, Student{name='至尊宝', age=28, height=169.6}, Student{name='牛魔王', age=48, height=169.6}]
1.4.2.1.2 方式二
◎通过调用TreeSet集合有参数构造器,可以设置Comparator对象(比较器对象,用于指定比较规则。
public TreeSet(Comparator<?super E> comparator)
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
public class SetTest1 {
public static void main(String[] args) {
//就近选择自己自带的比较器对象进行排序
Set<Student> students =new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
//需求:按照身高升序排序
return Double.compare(o1.getHeight(),o2.getHeight());
}
});
Student s1 = new Student("至尊宝",28,169.6);
Student s2 = new Student("蜘蛛精",23,169.6);
Student s3 = new Student("蜘蛛精",23,169.6);
Student s4=new Student( "牛魔王",48,169.6);
students.add(s1);
students.add(s2);
students.add(s3);
students.add(s4);
System.out.println(students);
}
}
简化写法
//就近选择自己自带的比较器对象进行排序
Set<Student> students =new TreeSet<>((o1, o2) -> Double.compare(o1.getHeight(),o2.getHeight()));
1.5 Collection集合的使用场景
- 1、如果希望记住元素的添加顺序,需要存储重复的元素,又要频繁的根据索引查询数据?
- 用ArrayList集合(有序、可重复、有索引),底层基于数组的。(常用)
- 2、如果希望记住元素的添加顺序,且增删首尾数据的情况较多?
- 用LinkedList集合(有序、可重复、有索引),底层基于双链表实现的。
- 3.如果不在意元素顺序,也没有重复元素需要存储,只希望增删改查都快?
- 用Hashset集合(无序,不重复,无索引),底层基于哈希表实现的。(常用)
- 4.如果希望记住元素的添加顺序,也没有重复元素需要存储,且希望增删改查都快?
- 用LinkedHashset集合(有序,不重复,无索引),底层基于哈希表和双链表
- 5.如果要对元素进行排序,也没有重复元素需要存储?且希望增删改查都快?
- 用Treeset集合,基于红黑树实现。