java – 集合类,集合概念,List接口->ArrayList、LinkedList,Idea的Debug功能,集合泛型


9.1、集合概念

集合框架:比数组更方便去做数据的 增/删/改/查

集合更方便的对数据进行操作

集合与数组比较:

数组特点:

  1. 数组只能保存多个同一种类型的数据
  2. 数组长度固定,想改变长度要手动扩容,Arrays.copyOf(srcArrays,newLength);
  3. 数组下标/索引从0开始

集合:可以简单理解为数组的升级版

  1. 集合默认可以保存多种类型的数据
  2. 集合长度不固定,自动扩容
  3. 集合下标/索引从0开始
  4. 集合处理数据的效率更高

集合框架的继承体系:

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 ,无序的

image

有序的:就是把元素放入集合的顺序和遍历出来的顺序是一致的。

无序的:就是把元素放入集合的顺序和遍历出来的顺序可能是不一致的。

9.2、Collection 接口

单列集合的根接口

  1. 添加元素
boolean 	add(E e) 			
 		  确保此 collection 包含指定的元素(可选操作)。 
  1. 清空所有元素
 boolean 	remove(Object o) 
          从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。 
  1. 判断集合中是否包含某元素
boolean	 	contains(Object o) 
          如果此 collection 包含指定的元素,则返回 true。 
  1. 判断集合中是否包含元素
boolean 	isEmpty() 
          如果此 collection 不包含元素,则返回 true。 
  1. 从集合中移除某个元素
boolean 	remove(Object o) 
          从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。 
  1. 得到集合的长度,即有多少个元素
int			 size() 
          返回此 collection 中的元素数。 
  1. 把集合转换为数组,返回一个对象数组
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基础功能解析:

image

Step over : 执行每一行的代码,不会进入自定义方法和jdk提供的

方法。

Step into: 会进入自定义方法和jdk提供的方法,但是jdk提供的方

法不会进入非常底层的代码

force Step into: 会进入非常底层代码

Step Out : 回到上一级执行的代码

要==深层 debug ==还要在设置中取消勾选 “Hide null ……” 和 “Enable alternative view……” 两栏

image

a)实现类:ArrayList

特点:

1)底层使用可变 Object 数组

2)有序的 – 数组

3)查询快,增删满

ArrayList集合的扩容机制

image

@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 的区别:

image

案例:

@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);
}

image

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类型

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/280190.html

(0)
上一篇 2022年8月13日
下一篇 2022年8月13日

相关推荐

发表回复

登录后才能评论