news 2026/4/15 6:07:26

模块十九.集合

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
模块十九.集合

1.Collections集合工具类

public class Demo1 { public static void main(String[] args) { ArrayList<Person> list = new ArrayList<>(); list.add(new Person("小刘",16)); list.add(new Person("小爱",18)); list.add(new Person("小话",17)); Collections.sort(list, new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { return o1.getAge()-o2.getAge(); } }); System.out.println(list); } } public class Person { private String name; private Integer age; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } @Override public String toString() { return "person{" + "age=" + age + ", name='" + name + '\'' + '}'; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } }

1.接口:Comparable接口

2.方法:int compareTo(T, o)->this-o(升序) o-this(降序)

public class Demo03 { public static void main(String[] args) { ArrayList<Student> list=new ArrayList<Student>(); list.add(new Student("小六",100)); list.add(new Student("小话",150)); list.add(new Student("小六",80)); Collections.sort(list); System.out.println(list); } }
public class Student implements Comparable<Student>{ private String name; private Integer score; public Student() { } public Student(String name, Integer score) { this.name = name; this.score = score; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getScore() { return score; } public void setScore(Integer score) { this.score = score; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", score=" + score + '}'; } @Override public int compareTo(Student o) { return this.getScore()-o.getScore(); } }

Arrays中的静态方法:

static <T> List<T> asList(T...a) ->直接指定元素,转存到list集合中

public class Demo04 { public static void main(String[] args) { List<String> list = Arrays.asList("张三","李四"); System.out.println(list); } }

2.泛型

1.泛型<>

2.作用

统一数据类型,防止将来的数据转换异常

3.注意:

a.泛型中的类型必须是引用数据类型

b.如果泛型不写默认是Object

1.为什么要使用泛型

1.从使用层面上来讲:

统一数据类型,防止将来的数据转换异常

2.定义层面上看:

定义带泛型的类、方法等,将来使用的时候给泛型确定什么类型,泛型就会变成什么类型,凡是涉及到泛型的都会变成确定的类型,代码更灵活

public class Demo01 { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add("1"); list.add(1); list.add("adc"); list.add(22); //获取元素中为String类型的字符串长度 for (Object o : list) { String s=(String) o; System.out.println(s.length());//ClassCastException } } }

2.泛型的定义

2.1含有泛型的类

1.定义:

public class 类名<E>{

}

2.什么时候确定类型

new对象的时候

public class MyArrayList <E>{ //定义一个数组,充当ArrayList底层的数组,长度为10 Object[] obj =new Object[10]; //定义size,代表集合元素个数 int size; /** * 定义一个add方法,参数类型需要和泛型类型一致 * * 数据类型为E 变量名随便起 */ public boolean add(E e){ obj[size] =e; size++; return true; } /** * 定义一个get方法,根据索引获取元素 */ public E get(int index){ return (E) obj[index]; } @Override public String toString() { return "MyArrayList{" + "obj=" + Arrays.toString(obj) + ", size=" + size + '}'; } }
public class Demo02 { public static void main(String[] args) { MyArrayList<String> list1=new MyArrayList<>(); list1.add("111"); list1.add("222"); System.out.println(list1);//直接输出list1,默认调用toString方法 } }
2.2含有泛型的方法

1.格式:

修饰符 <E> 返回值类型 方法名(E e)

2.什么时候确定类型

调用的时候确定类型

public class ListUtils { //定义一个静态方法addAll,添加多个集合的元素 public static <E> void addAll(ArrayList<E> list,E ... e){ for (E e1 : e) { list.add(e1); } } }
public class Demo3 { public static void main(String[] args) { ArrayList<String> list=new ArrayList<>(); ListUtils.addAll(list,"a","b"); System.out.println(list); } }
2.3含有泛型的接口

1.格式

public interface 接口名<E>{

}

2.什么时候确定类型:

a.在实现类的时候还没有确定类型,只能在new实现类的时候确定类型了 ->ArrayList

b.在实现类就直接确定类型 ->比如Scanner

public interface MyList <E>{ public boolean add(E e); }
public class MyArrayList1<E> implements MyList<E>{ //定义一个数组,充当ArrayList底层的数组,长度为10 Object[] obj =new Object[10]; //定义size,代表集合元素个数 int size; /** * 定义一个add方法,参数类型需要和泛型类型一致 * * 数据类型为E 变量名随便起 */ public boolean add(E e){ obj[size] =e; size++; return true; } /** * 定义一个get方法,根据索引获取元素 */ public E get(int index){ return (E) obj[index]; } @Override public String toString() { return "MyArrayList{" + "obj=" + Arrays.toString(obj) + ", size=" + size + '}'; } }
public class Demo04 { public static void main(String[] args) { MyArrayList1<String> list1=new MyArrayList1<>(); list1.add("斩杀"); list1.add("斩杀"); list1.add("斩杀"); System.out.println(list1); } }
public interface MyIterator <E>{ E next(); }
public class MyScanner implements MyIterator<String>{ @Override public String next() { return "小刘和小莱"; } }
public class Demo05 { public static void main(String[] args) { MyScanner myScanner=new MyScanner(); String reault =myScanner.next(); System.out.println("result = "+reault); } }

3.泛型的高级使用

3.1泛型通配符?
public class Demo01 { public static void main(String[] args) { ArrayList<String> list1=new ArrayList<>(); list1.add("张三"); list1.add("李四"); ArrayList<Integer> list2=new ArrayList<>(); list2.add(111); list2.add(222); method(list1); method(list2); } private static void method(ArrayList<?> list) { for (Object o : list) { System.out.println(o); } } }
3.2泛型的上限下限

1.作用:可以规定泛型的范围

2.上限:

a.格式:<? extends 类型>

b.含义:?只能接收extends后面的本类类型以及子类类型

3.下限:

a.格式:<? super 类型>

b.含义:?只能接收super后面的本类类型以及父类类型

/** * Integer ->Number ->Object * String ->Object */ public class Demo02 { public static void main(String[] args) { ArrayList<Integer> list1=new ArrayList<>(); ArrayList<String> list2=new ArrayList<>(); ArrayList<Number> list3=new ArrayList<>(); ArrayList<Object> list4=new ArrayList<>(); get1(list1); //get1(list2);错误 get1(list3); //get1(list4);错误 System.out.println("===================="); //get2(list1);错误 //get2(list2);错误 get2(list3); get2(list4); } //上限 ?只能接收extends后面的本类类型及子类类型 private static void get1(Collection<? extends Number> collection) { } //下限 ?只能接收super后面的本类类型及父类类型 private static void get2(Collection<? super Number> collection) { } }

应用场景:

1.如果我们在定义类、方法、接口时,如果类型不确定,我们可以考虑定义含有泛型的类、方法、接口

2.如果类型不确定,但是能知道以后只能传递某个类的继承体系中的子类或父类,可以使用泛型中的通配符

3.斗地主案例(拓展案例)

3.1案例介绍

3.2案例分析

3.3代码实现

1.创建ArrayList集合->color ->专门存花色

2.创建ArrayList集合->number ->专门存牌号

3.创建ArrayList集合->poker ->专门存花色和牌号组合

4.打乱poker

5.创建4个ArrayList集合,分别代表三个玩家,以及一个存储一个底牌

6.如果index为最后三张,往底牌集合中存

7.如果index%3==0 给p1

8.如果index%3==1 给p2

9.如果index%3==2 给p3

10.遍历看牌

4.红黑树

集合中加入红黑树的目的:提高查询效率

HashSet集合:

数据结构:哈希表

jdk8之前:哈希表=数组+链表

jdk8之后:哈希表=数组+链表+红黑树->提高查询效率

5.Set集合

1.Set接口并没有对Collection接口进行功能上的扩充,而且所有的Set集合底层都是依靠Map实现

1.Set集合介绍

Set和Map密切相关

Map的遍历需要先变成单列集合,只能变成set集合

2.HashSet集合的介绍和使用

1.概述:HashSet是Set接口的实现类

2.特点:

a.元素唯一

b.元素无序

c.无索引

d.线程不安全

3.数据结构:哈希表

a.jdk8之前:哈希表 = 数组+链表

b.jdk8之后:哈希表 = 数组+链表+红黑树

加入红黑树目的:查询快

4.方法:和Collection一样

5.遍历:

a.增强for

b.迭代器

public class Demo01 { public static void main(String[] args) { HashSet<String> set=new HashSet<>(); set.add("li"); set.add("lihua"); set.add("lippp"); System.out.println(set); //迭代器 Iterator<String> integer=set.iterator(); while (integer.hasNext()){ System.out.println(integer.next()); } System.out.println("=============="); //增强for for (String s : set) { System.out.println(s); } } }

3.LinkedHashSet集合的介绍和使用

1.概述:LinkedHashSet extends HashSet

2.特点:

a.元素唯一

b.元素有序

c.无索引

d.线程不安全

3.数据结构:

哈希表+双向链表

4.使用:和HashSet一样

public class Demo01 { public static void main(String[] args) { LinkedHashSet<String> set=new LinkedHashSet<>(); set.add("li"); set.add("lihua"); set.add("lippp"); System.out.println(set); //迭代器 Iterator<String> integer=set.iterator(); while (integer.hasNext()){ System.out.println(integer.next()); } System.out.println("=============="); //增强for for (String s : set) { System.out.println(s); } } }

4.哈希值

1.概述:是由计算机算出来的一个十进制数,可以看作是对象的地址值

2.获取对象的哈希值,使用的是Object中的方法

public native int hashCode()

3.注意:如果重写了hashCode方法,那计算的就是对象内容的哈希值了

4.总结:

a.哈希值不一样,内容肯定不一样

b.哈希值一样,内容也有可能不一样

如果不重写hashCode方法,默认计算对象的哈希值

如果重写hashCode方法,计算对象内容的哈希值

5.字符串的哈希值是如何算出来的

问题:在计算哈希值的时候,有一个定值就是31,为啥?

31是一个质数,31这个数通过大量的计算,认为用31,可以尽量降低内容不一样但是哈希值一样的情况

内容不一样,哈希值一样(哈希冲突,哈希碰撞)

6.HashSet的存储去重复的过程

1.先计算元素的哈希值(重写hashCode方法),再比较内容(重写equals方法)

2.先比较哈希值,如果哈希值不一样,存

3.如果哈希值一样,再比较内容

a.如果哈希值一样,内容不一样,存

b.如果哈希值一样,内容也一样,去重复

7.HashSet存储自定义类型如何去重复?

总结:

1.如果HashSet存储自定义类型,如何去重复?

重写hashCode和equals方法,让HashSet比较属性的哈希值和属性的内容

2.如果不重写hashCode和equals方法,默认调用的是Object的,不同的对象肯定哈希值不一样,equals比较对象的地址值也不一样,所以此时即使对象的属性值一样,也不能去重复

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/12 15:18:32

32、Linux系统磁盘管理与打印操作全解析

Linux系统磁盘管理与打印操作全解析 1. 磁盘空间查看 在Linux系统中,我们可以使用 df 命令来查看系统磁盘的剩余空间。具体操作是在终端中输入以下命令: $ df RET执行该命令后,会输出类似如下的结果: | Filesystem | 1024−blocks | Used | Available | Capacity | …

作者头像 李华
网站建设 2026/4/11 11:08:02

Python实时外汇汇率监控板:利用Playwright与异步技术构建智能爬虫系统

引言:外汇数据监控的重要性与挑战 在全球化的经济环境中,外汇汇率波动直接影响国际贸易、投资决策和个人理财。无论是跨境电商经营者、海外投资者,还是计划出国旅行的个人,实时掌握汇率变化都至关重要。然而,外汇市场数据具有高频率更新、多数据源、结构复杂等特点,传统…

作者头像 李华
网站建设 2026/4/11 15:24:24

git add 后pull 放弃本地所有修改

两台电脑代码有差别&#xff0c;pull报错&#xff0c;当前电脑修改可以完全放弃&#xff0c;但是pull提示有代码已经add过&#xff0c;强行pull当前项目变为merge模式。git pullgit clean -fd // 如果本地没add的话&#xff0c;该命令应该可以直接清除本地修改git reset --hard…

作者头像 李华
网站建设 2026/4/3 13:09:19

BioSIM抗人TNFSF2/TNFα抗体SIM0348:专业品质与品牌保障

在现代生命科学的研究中&#xff0c;抗体作为关键工具&#xff0c;广泛应用于免疫学、细胞生物学及药物开发等多个领域。其中&#xff0c;针对肿瘤坏死因子α&#xff08;TNFα&#xff09;及其受体&#xff08;TNFSF2&#xff09;的抗体&#xff0c;因其在炎症反应、自身免疫疾…

作者头像 李华
网站建设 2026/4/13 13:33:12

SQL必会必知整理-09-使用数据处理函数

9.1 函数函数一般是在数据上执行的&#xff0c;它给数据的转换和处理提供了方便。能运行在多个系统上的代码称为可移植的&#xff08;portable&#xff09;。相对来说&#xff0c;多数SQL语句是可移植的&#xff0c;在SQL实现之间有差异时&#xff0c;这些差异通常不那么难处理…

作者头像 李华
网站建设 2026/4/12 12:20:42

19、文本处理与分析全攻略

文本处理与分析全攻略 在日常的文本处理和分析中,我们常常需要用到各种工具和方法来完成不同的任务,比如查找同义词、检查语法、统计文本信息以及分析文本相关性等。下面将为大家详细介绍这些工具和方法的使用。 查找词汇的上位词 上位词是指含义比给定词汇更宽泛的相关词…

作者头像 李华