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,System,泛型,集合,println,out 来源: https://www.cnblogs.com/hwphwc/p/16581810.html