java - 集合类,集合概念,List接口->ArrayList、LinkedList,Idea的Debug功能,集合泛型
2022/8/13 14:22:58
本文主要是介绍java - 集合类,集合概念,List接口->ArrayList、LinkedList,Idea的Debug功能,集合泛型,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
9.1、集合概念
集合框架:比数组更方便去做数据的 增/删/改/查
集合更方便的对数据进行操作
集合与数组比较:
数组特点:
- 数组只能保存多个同一种类型的数据
- 数组长度固定,想改变长度要手动扩容,
Arrays.copyOf(srcArrays,newLength);
- 数组下标/索引从0开始
集合:可以简单理解为数组的升级版
- 集合默认可以保存多种类型的数据
- 集合长度不固定,自动扩容
- 集合下标/索引从0开始
- 集合处理数据的效率更高
集合框架的继承体系:
Collection 层次结构 中的根接口
Collection :单列结构根接口
|----- List 子接口:有序的
|----- ArrayList 实现类:底层是可变(自动扩容)数组(Object)可以放入重复的元素。查询速度快,增/删 速度慢。
|-----LinkedList 实现类:底层是双向链表的结构,可以放入重复的元素。查询速度慢,增/删 速度快。
|-----Vector 实现类:跟 ArrayList 非常相似
|-----Set 子接口:不重复的元素
|-----HashSet 实现类:通过 Hash 算法计算元素放的位置,无序的,不重复的元素
|-----LinkedHashSet 实现类:基于 Hash 表和链表结构实现的,有序的,不重复的元素
Map:双列结构,以 key :键 和 value :值 2个维度来保存数据。
|-----HashMap:键:Key 不能重复,值:value 可以重复,但是 key 和 value 可以为 null ,无序的
|-----Hashtable:键:Key 不能重复,值:value 可以重复,但是 key 和 value 都不能为 null ,无序的
有序的:就是把元素放入集合的顺序和遍历出来的顺序是一致的。
无序的:就是把元素放入集合的顺序和遍历出来的顺序可能是不一致的。
9.2、Collection 接口
单列集合的根接口
- 添加元素
boolean add(E e) 确保此 collection 包含指定的元素(可选操作)。
- 清空所有元素
boolean remove(Object o) 从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。
- 判断集合中是否包含某元素
boolean contains(Object o) 如果此 collection 包含指定的元素,则返回 true。
- 判断集合中是否包含元素
boolean isEmpty() 如果此 collection 不包含元素,则返回 true。
- 从集合中移除某个元素
boolean remove(Object o) 从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。
- 得到集合的长度,即有多少个元素
int size() 返回此 collection 中的元素数。
- 把集合转换为数组,返回一个对象数组
Object[] toArray() 返回包含此 collection 中所有元素的数组。
9.3、List 接口
常用方法
1.得到集合中元素的索引位置
int indexOf(Object o) 返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
2.根据索引位置移除元素
E remove(int index) 移除列表中指定位置的元素(可选操作)。
3.在指定的位置插入元素
void add(int index, E element) 在列表的指定位置插入指定元素(可选操作)。 index:元素的索引位置 element: 插入的元素
4.在指定位置设置元素
E set(int index, E element) 用指定元素替换列表中指定位置的元素(可选操作)。
5.获取指定位置上的元素
E get(int index) 返回列表中指定位置的元素。
Debug基础功能解析:
Step over : 执行每一行的代码,不会进入自定义方法和jdk提供的
方法。
Step into: 会进入自定义方法和jdk提供的方法,但是jdk提供的方
法不会进入非常底层的代码
force Step into: 会进入非常底层代码
Step Out : 回到上一级执行的代码
要==深层 debug ==还要在设置中取消勾选 "Hide null ......" 和 "Enable alternative view......" 两栏
a)实现类:ArrayList
特点:
1)底层使用可变 Object 数组
2)有序的 - 数组
3)查询快,增删满
ArrayList集合的扩容机制
@Test public void test01(){ //创建集合对象 //向上转型 List list = new ArrayList(); //添加元素 list.add("小黄"); list.add(168); list.add(true); list.add(22); list.add(4,"小黄"); System.out.println("list = " + list); //集合的元素都是 Object,所有的类都继承自 Object类 //list.clear(); System.out.println("list = " + list); boolean bool = list.contains("小黄"); System.out.println("bool = " + bool); System.out.println("集合中是否包含元素?" + list.isEmpty()); boolean bool2 = list.remove("小黄"); //从列表中移除项的第一次出现。 System.out.println("bool2 = " + bool2); System.out.println("list = " + list); System.out.println("集合的长度:" + list.size()); Object[] objects = list.toArray(); System.out.println(Arrays.toString(objects)); int index = list.indexOf("小黄"); System.out.println("index = " + index); Object object = list.remove(1); // .remove(int index) 的返回类型应该是 Object System.out.println("object = " + object); //object = true //boolean bool4 = list.remove(168); //错误 list.remove(Integer.valueOf(168)); //当移除的是元素是一个数字的时候,需要将该数据转换成相应数据类型的包装类的对象 System.out.println(); }
b)实现类:LinkedList
特点:
底层实现双向链表,有序的,可以放重复元素,查询慢,增删快
常用方法:
void addFirst(E e) 将指定元素插入此列表的开头。
void addLast(E e) 将指定元素添加到此列表的结尾。
E getFirst() 返回此列表的第一个元素。 E getLast() 返回此列表的最后一个元素
E removeFirst() 移除并返回此列表的第一个元素。 E removeLast() 移除并返回此列表的最后一个元素。
关于链表的解释:
public class TestLinkedList { public static void main(String[] args) { //创建三个Node对象 Node jack = new Node("jack"); Node tom = new Node("tom"); Node brown = new Node("brown"); //用节点连接起来,形成双向链表 jack.next = tom; tom.next = brown; brown.prev = tom; tom.prev = jack; //给 first 和 last 节点指向 Node first = jack; Node last = brown; //正向 - 遍历出当前的双向连接结构 while (true){ if (first == null){ break; } System.out.print(first + "\t"); first = first.next; } System.out.println("\n"); //反向 - 遍历出当前的双向连接结构 while (true){ if (last == null){ break; } System.out.print(last + "\t"); last = last.prev; } //在 tom 和 brown 之间添加一个 green //创建一个 green 节点 Node green = new Node("green"); //重新设置节点指向 tom.next = green; green.prev = tom; green.next = brown; brown.prev = green; //重新设置first,last,让它们归位 first = jack; last = brown; System.out.println("\n"); //正向 - 遍历出当前的双向连接结构 while (true){ if (first == null){ break; } System.out.print(first + "\t"); first = first.next; } } } //自定义节点类 class Node{ //存放节点,可以存放任何类型 public Object item; //定义节点 public Node next; public Node prev; public Node(Object item) { this.item = item; } @Override public String toString() { return item + ""; } }
ArrayList 和 LinkedList 的区别:
案例:
@Test public void test01(){ LinkedList list = new LinkedList(); list.add("郭德纲"); list.add("柳岩"); list.add("李易峰"); list.add("李易峰"); list.addFirst("郭麒麟"); list.addLast("小黄"); System.out.println("list = " + list); list.add(2,"迪丽热巴"); System.out.println("list = " + list); Object o = list.removeFirst(); System.out.println("o = " + o); System.out.println("list = " + list); }
c)实现类:Vector
1)底层是可变的 Object 数组
2)有序的,可以放重复元素
3)查询快,增删慢
4)Vector 是线程同步的,即线程安全
5)在开发中,需要线程同步安全时,考虑使用 Vector
9.4、集合遍历
1、普通 for 循环
2、增强 for 循环
3、迭代器
通过迭代的方式,把集合中的元素,依次获取
步骤:
1)获取迭代器的对象
Iterator<E> iterator() 返回按适当顺序在列表的元素上进行迭代的迭代器
2)通过 hasNext 方法判断是否还有下一个元素
boolean hasNext() 如果仍有元素可以迭代,则返回 true
3)如果有下一个元素,那么就得到它
E next() 返回迭代的下一个元素
9.5、如何在集合中存储对象
在ArrayList中存储3个员工,每个员工要保存的信息是员工编号,员工姓名,员工年龄。并演示3种方式进行迭代,输出员工的信息。
import java.util.Objects; public class Emp { private String empId; private String empName; private int empAge; public String getEmpId() { return empId; } public void setEmpId(String empId) { this.empId = empId; } public String getEmpName() { return empName; } public void setEmpName(String empName) { this.empName = empName; } public int getEmpAge() { return empAge; } @Override public String toString() { return "Emp{" + empId + ", " + empName + ", " + empAge + '}'; } public void setEmpAge(int empAge) { this.empAge = empAge; } public Emp(String empId, String empName, int empAge) { this.empId = empId; this.empName = empName; this.empAge = empAge; } } public class EmpList { @Test public void test01(){ ArrayList list = new ArrayList(); list.add(new Emp("1","张三",17)); list.add(new Emp("2","李四",18)); list.add(new Emp("3","王五",19)); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } System.out.println("\n================="); for (Object obj : list) { System.out.println(obj); } System.out.println("\n================="); Iterator iterator = list.iterator(); while (iterator.hasNext()){ Object obj = iterator.next(); System.out.println(obj); } Emp emp = new Emp("1", "张三", 17); System.out.println(list.contains(emp)); } }
9.6、如何实现对象的比较
上题ArrayList中如果有对象Emp emp= new Emp("1","张三",17);请通过程序判断集合中是否包含此元素。 Emp = Employee
//Emp 类中重写 equals 方法 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Emp emp = (Emp) o; return empAge == emp.empAge && Objects.equals(empId, emp.empId) && Objects.equals(empName, emp.empName); } @Override public int hashCode() { return Objects.hash(empId, empName, empAge); } //测试类中查找 Emp emp = new Emp("1", "张三", 17); System.out.println(list.contains(emp));
9.7、并发修改异常
集合遍历时,进行集合元素的修改/添加等操作。
需求:定义一个集合,往集合中添加三个字符串,遍历集合;如果在遍历过程中发现有"abc",我们就向集合中再添加一个字符串"mm"
@Test public void test04(){ /** * 需求: * * 定义一个集合,往集合中添加三个字符串,遍历集合 * * 如果在遍历过程中发现有"abc",我们就向集合中再添加一个字符串"mm" */ //Arrays.asList():可以把数组直接转换为集合的类型 List list = new ArrayList(); list.add("abc"); list.add("bcd"); list.add("cvf"); //遍历集合时,普通for循环,可以添加元素 /* for (int i = 0; i < list.size(); i++) { String ele = (String) list.get(i); if(ele.equals("abc")){ list.add("mm"); } }*/ //遍历集合时,增强for循环,不能添加/删除元素 /*for (Object obj : list) { String ele = (String) obj; if(ele.equals("abc")){ list.remove("cvf"); } }*/ //遍历集合时,迭代器,不能添加/删除元素 Iterator iterator = list.iterator(); while (iterator.hasNext()){ Object obj = iterator.next(); String ele = (String) obj; if(ele.equals("abc")){ list.add("mm"); } } System.out.println("list = " + list); }
9.8、集合泛型
泛型的分类
1)集合类上使用泛型
语法:集合类型<对象数据类型> 集合对象 = new 集合类型();
2)类上定义泛型
定义:具有1个或者多个泛型变量的类叫做泛型类。这个泛型的变量
可以是成员变量,也可以是方法的参数或者返回值。
作用:让类具有通用性,T:并不具体什么类型,只有放入之后,才能知道是什么类型。
3)方法上定义泛型
定义:在方法的返回值的前面添加一个
方法。
作用:让方法具有通用性,T:并不具体什么类型,只有放入之后,才能知道是什么类型。
注意:如果一个类是 普通类,但是想使用泛型,那么就只能定义成 泛型方法
4)接口上定义泛型
定义:接口中的方法的返回值或者参数是泛型的接口就是所谓泛型
接口。
5)迭代器以及增强 for 循环
Java泛型中的标记符含义:
E - Element (在集合中使用,因为集合中存放的是元素) T - Type(Java 类) K - Key(键) V - Value(值) N - Number(数值类型) ? - 表示不确定的java类型
这篇关于java - 集合类,集合概念,List接口->ArrayList、LinkedList,Idea的Debug功能,集合泛型的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-25JAVA语音识别项目项目实战入门教程
- 2024-11-25JAVA云原生项目实战入门教程
- 2024-11-25Java语音识别项目入门:新手必读指南
- 2024-11-25Java语音识别项目入门:轻松开始你的第一个语音识别项目
- 2024-11-25Java语音识别项目入门详解
- 2024-11-25Java语音识别项目教程:从零开始的详细指南
- 2024-11-25JAVA语音识别项目教程:初学者指南
- 2024-11-25Java语音识别项目教程:初学者指南
- 2024-11-25JAVA云原生入门:新手指南与基础教程
- 2024-11-25Java云原生入门:从零开始的全面指南