Java基础知识(二十七)集合(二)

本文详细介绍了Java集合框架中List接口的三个主要子类ArrayList、Vector和LinkedList的特性、常用方法及其在实际编程中的应用。通过实例演示了如何使用这些类进行元素的添加、删除、获取,以及如何处理重复元素。同时,文章还指出了在处理重复元素时需要注意的 equals 方法重写问题,强调了线程安全性和效率在选择集合类时的重要性。
摘要由CSDN通过智能技术生成

目录

一、List接口的子类

1、ArrayList类

2、Vector类 

Vector类特有的方法

3、LinkedList类

LinkedList类中的特有方法


一、List接口的子类

1、ArrayList类

ArrayList类的底层逻辑是数组。具有查询快,增删慢的特点,线程不安全,效率高

ArrayList案例:

需求一:使用ArrayList存储字符串并遍历(如果有重复的需要去除)

代码实现:

import java.util.ArrayList;
import java.util.Iterator;
 
public class ArrayTest1 {
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        arrayList.add("hello");
        arrayList.add("world");
        arrayList.add("java");
        arrayList.add("bigdata");
        arrayList.add("hive");
        arrayList.add("spark");
        arrayList.add("bigdata");
        System.out.println("去重之前的集合:"+arrayList);
//        创建第二个集合对象存放去重之后的集合
        ArrayList list2 = new ArrayList();
//        创建迭代器对象
        Iterator iterator = arrayList.iterator();
//        遍历
        while(iterator.hasNext()){
            String s=(String)iterator.next();
            if(!list2.contains(s)){
                list2.add(s);
            }
//            如果list2中没有该元素,就添加该元素到list2集合中
        }
        System.out.println("去重之后的集合:"+list2);
    }
}

这里集合中bigdata元素重复了一次,需要去除,输出结果:

 需求二:使用ArrayList存储自定义对象并遍历(并去重)

学生对象,姓名和年龄都一样的时候,表示的是同一个人

代码实现:

先创建学生类:

public class Students {
    private String name;
    private int age;
 
    public Students() {
    }
 
    public Students(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    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;
    }
 
    @Override
    public String toString() {
        return "Students{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

 再定义ArrayList类进行进一步操作:

import java.util.ArrayList;
import java.util.Iterator;
 
public class ArrayTest2 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        Students s1 = new Students("张翼德", 20);
        Students s2 = new Students("赵云", 17);
        Students s3 = new Students("张翼德", 20);
        list.add(s1);
        list.add(s2);
        list.add(s3);
        System.out.println("去重前的集合:");
        System.out.println(list);
        ArrayList list2 = new ArrayList();//定义第二个集合存储去重后的集合
        Iterator iterator = list.iterator();
//        遍历
        while(iterator.hasNext()){
            Students s=(Students)iterator.next();
            if(!list2.contains(s)){
                list2.add(s);
            }
        }
        System.out.println("去重后的集合:");
        System.out.println(list2);
    }
}

输出结果:

根据输出结果来看,虽然实现了遍历,但是并没有实现去重效果,通过分析发现可能是再if判断中出现了问题。

分析:if语句行,只有当if语句为true时,才会执行添加功能,根据输出结果来看,if语句始终是true,也就是说contains方法并没有生效。这是需要进入到contains方法底层实现中去查看

以下为contains的底层实现:
 

public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }
 
    /**
     * Returns the index of the first occurrence of the specified element
     * in this list, or -1 if this list does not contain the element.
     * More formally, returns the lowest index <tt>i</tt> such that
     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
     * or -1 if there is no such index.
     */
    public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))//调用的是equals方法
                    return i;
        }
        return -1;
    }

通过观察底层实现发现contains底层调用的是equals方法,而上述Students类中并没有重写equals方法,因此这里调用的是Object类中的equals方法,故比较的是地址值,学生对象都是new出来的,所以对象地址值必然不一样。故equals结果永远为false,回到if语句中加上!就永远为true,所以无论如何都会添加到新集合中,最终没有实现去重。

解决办法:在元素类Students加入重写equals方法即可,可自动生成。其他代码不变。

 //重写的equals方法
@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Students students = (Students) o;
        return age == students.age && Objects.equals(name, students.name);
    }

输出结果:

2、Vector类 

底层数据结构是数组,查询快,增删慢,线程安全,效率低(虽然安全,但实际开发不使用)

Vector类特有的方法

 public void addElement(Object obj) 将元素添加到集合的末尾 效果上和add()一样

public Object elementAt(int index) 获取指定索引处的元素

get(int index) public Enumeration elements() 返回此向量的组件的枚举。

Vector类举例实现与ArrayList类基本相同,只是方法名不同而已。

代码举例:

import java.util.Enumeration;
import java.util.Vector;
public class VectorDemo {
    public static void main(String[] args) {
        //创建Vector集合对象
        Vector vector = new Vector();
 
        //向集合添加元素
        vector.addElement("hello");
        vector.addElement("java");
        vector.add("world");
        vector.addElement("java");
 
//        System.out.println(vector);
 
//public Object elementAt(int index)获取指定索引处的元素    get(int index)
        Object o = vector.elementAt(0);
        System.out.println(o);
        System.out.println(vector.elementAt(1));
        System.out.println(vector.elementAt(2));
        System.out.println(vector.elementAt(3));
//        System.out.println(vector.elementAt(4));
        System.out.println(vector.get(3));
 
        System.out.println("=============================================");
        //public Enumeration elements()  返回此向量的元素的枚举。
        //简单记忆 你就把这个对象看作成一个迭代器
        Enumeration elements = vector.elements();
        while (elements.hasMoreElements()) {
            Object o1 = elements.nextElement();
            String s = (String) o1;
            System.out.println(s);
        }
 
 
    }
}

3、LinkedList类

底层数据结构是双链表,查询慢,增删快。线程是不安全的,效率高

LinkedList类中的特有方法

1、添加功能:

public void addFirst(Object e) 在集合的开头添加元素

addLast(Object e) 在结合末尾添加元素,等同于add()方法

2、获取功能:

public Object getFirst() 获取集合中的第一个元素

getLast() 获取集合中的最后一个元素

3、删除功能:

public Object removeFirst() 从集合中删除第一个元素并返回

public Object removeLast() 从集合中删除最后一个元素并返回

 具体功能实现代码举例:
 

import java.util.LinkedList;
 
public class LinkedTest1 {
    public static void main(String[] args) {
        LinkedList list = new LinkedList();
        list.add("hello");
        list.add("world");
        list.add("java");
        System.out.println(list);
//        在集合开头添加元素
        list.addFirst("bigdata");
        System.out.println("开头添加元素:");
        System.out.println(list);
//        在集合末尾添加元素
        list.addLast("superman");
        System.out.println("末尾添加元素:");
        System.out.println(list);
//        获取集合第一个元素
        System.out.println("获取第一个元素:"+list.getFirst());
        System.out.println(list);
//        获取集合最后一个元素
        System.out.println("获取最后一个元素:"+list.getLast());
        System.out.println(list);
//        删除第一个元素
        System.out.println("删除第一个元素"+list.removeFirst());
        System.out.println("删除后的集合:"+list);
 
//        删除最后一个元素
        System.out.println("删除最后一个元素:"+list.removeLast());
        System.out.println("删除后的集合:"+list);
 
    }
}

输出结果:

案例: 

 需求:

请使用LinkedList模拟栈数据结构的集合,并测试

分析:题意是需要我们自己设计一个集合类,它的底层逻辑实现是LinkedList类,再调用自己的方法去实现栈数据结构

代码实现:

自己设计的集合类MineStack:

import java.util.LinkedList;
 
public class MineStack {
 
    private LinkedList linkedList;
//无参构造,底层为LinkedList无参构造创建对象
    MineStack(){
        LinkedList linkedList = new LinkedList();
    }
//    底层调用linkedList中的添加第一个元素
    void Mineadd(Object obj){
         linkedList.addFirst(obj);
    }
    public boolean ismyEmpty(){
        return linkedList.isEmpty();
    }
//    底层调用为删除第一个元素并返回
    public Object mineGet(){
        return linkedList.removeFirst();
    }
}

由于栈数据结构的特点是先进后出,所以我们需要使用LinkedList类中的removeFirst方法删除第一个元素并返回,这样第二个元素就变成了第一个元素,在下一次遍历时就可以输出该元素,最终实现先进后出,直到集合为空停止

测试类MineStackTest

public class MIneStackTest {
    public static void main(String[] args) {
//        创建对象
        MineStack stack = new MineStack();
//        添加数据到集合
        stack.Mineadd("hello");
        stack.Mineadd("world");
        stack.Mineadd("java");
        stack.Mineadd("bigdata");
 
//        遍历判断是否含有元素.含有就删除第一个元素并输出该元素
        while(!stack.ismyEmpty()){
            Object o = stack.mineGet();
            System.out.println(o);
        }
    }
}

输出结果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值