JavaSEDemo24集合ArrayList、LinkedList、HashSet、TreeSet

简介

  • 本文是2021/04/23整理的笔记
  • 赘述可能有点多,还请各位朋友耐心阅读
  • 本人的内容和答案不一定是最好最正确的,欢迎各位朋友评论区指正改进

ArrayList

ForEach删除容易出错

  • 增强for循环不能删除东西,会出现ConcurrentModification 并发修改异常
    @Test
    public void testForEachDel(){
        ArrayList<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(20);
        list.add(30);
        for (Integer integer : list) {
            System.out.println("integer = " + integer);
            boolean remove = list.remove(new Integer(20));
            System.out.println("remove = " + remove);
        }
        System.out.println(list);
    }

迭代器使用list.remove也不能删除,会报错

@Test
    public void testIteratorDel(){
        ArrayList<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(20);
        list.add(30);
        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()){
            Integer next = iterator.next();
            System.out.println("next = " + next);
            boolean remove = list.remove(new Integer(20));
            System.out.println("remove = " + remove);
        }
    }

迭代器remove可以删除 iterator.remove

@Test
    public void testIteratorRemove(){
        ArrayList<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(20);
        list.add(30);
        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()){
            Integer next = iterator.next();
            System.out.println("next = " + next);
            iterator.remove();
        }
        System.out.println("list = " + list);
    }

LinkedList

常用方法1

  • add(E e) 将指定元素添加到此列表的结尾。
  • addFirst(E e) 将指定元素插入此列表的开头。
  • addLast(E e) 将指定元素添加到此列表的结尾
  • element() 获取但不移除此列表的头(第一个元素)
  • getFirst() 返回此列表的第一个元素
  • getLast() 返回此列表的最后一个元素
  • peek() 获取但不移除此列表的头(第一个元素)。
  • peekFirst() 获取但不移除此列表的第一个元素;如果此列表为空,则返回 null
  • peekLast() 获取并移除此列表的第一个元素;如果此列表为空,则返回 null
  • poll() 获取并移除此列表的头(第一个元素)
  • pollFirst() 获取并移除此列表的第一个元素;如果此列表为空,则返回 null
  • pollLast() 获取并移除此列表的最后一个元素;如果此列表为空,则返回 null
  • push(E e) 将元素推入此列表所表示的堆栈
  • pop() 从此列表所表示的堆栈处弹出一个元素
  • remove(int index) 移除此列表中指定位置处的元素。
  • removeFirst() 移除并返回此列表的第一个元素。
@Test
    public void testAdd(){
        LinkedList<String> list = new LinkedList<>();
        list.add("刘备");
        list.add("关羽");
        list.addFirst("诸葛亮");
        list.addLast("赵云");
        list.offer("孙尚香");
        list.offerFirst("黄忠");
        list.offerLast("马超");
        System.out.println("list = " + list);
        //System.out.println("list.element() = " + list.element());
        //System.out.println("list.getFirst() = " + list.getFirst());
        //System.out.println("list.getLast() = " + list.getLast());
        //System.out.println("list.peek() = " + list.peek());
//        System.out.println("list.peekFirst() = " + list.peekFirst());
//        System.out.println("list.peekLast() = " + list.peekLast());
//        System.out.println("list.poll() = " + list.poll());
//        System.out.println("list.pollFirst() = " + list.pollFirst());
//        System.out.println("list.pollLast() = " + list.pollLast());
//        list.push("张飞");
//        System.out.println("list.pop() = " + list.pop());
//        System.out.println("list.remove() = " + list.remove());
//        System.out.println("list.removeFirst() = " + list.removeFirst());
        System.out.println("list.removeLast() = " + list.removeLast());
        System.out.println("=====================");


        System.out.println("list = " + list);
    }

常用方法2

  • removeFirstOccurrence 从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表时)
  • removeLastOccurrence从此列表中移除最后一次出现的指定元素(从头部到尾部遍历列表时)
  • toArray 返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组。
@Test
    public void testRemove(){
        LinkedList<String> list = new LinkedList<>();
        list.add("刘备");
        list.add("关羽");
        list.add("关羽");
        list.add("张飞");
        list.add("关羽");
        list.add("关羽");
        list.add("关羽");
        System.out.println("list = " + list);

//        boolean b = list.removeFirstOccurrence("关羽");
        boolean b = list.removeLastOccurrence("关羽");
        System.out.println("b = " + b);
        System.out.println("=====================");

        System.out.println("list = " + list);
        /*
        Object[] objects = list.toArray();
        for (Object object : objects) {
            System.out.println("object = " + object);
        }*/

        String[] array = list.toArray(new String[0]);
        for (String s : array) {
            System.out.println("s = " + s);
        }
    }
}

Stack

常用方法

  • push(E item) 把项压入堆栈顶部。
  • pop() 移除堆栈顶部的对象,并作为此函数的值返回该对象
  • peek()查看堆栈顶部的对象,但不从堆栈中移除它。
  • empty() 测试堆栈是否为空
  • search(Object o)返回对象在堆栈中的位置,以 1 为基数。如果对象 o 是堆栈中的一个项,此方法返回距堆栈顶部最近的出现位置到堆栈顶部的距离;堆栈中最顶部项的距离为 1。使用 equals 方法比较 o 与堆栈中的项。
 @Test
    public void testPush(){
        Stack<String> stack = new Stack<String>();
        stack.push("刘备");
        stack.push("关羽");
        stack.push("张飞");
        System.out.println("stack = " + stack);
        /*System.out.println("stack.pop() = " + stack.pop());
        System.out.println("stack.pop() = " + stack.pop());
        System.out.println("stack.pop() = " + stack.pop());*/


      /*  System.out.println("stack.peek() = " + stack.peek());
        System.out.println("stack.peek() = " + stack.peek());
        System.out.println("stack.peek() = " + stack.peek());*/

        System.out.println("stack.empty() = " + stack.empty());
        System.out.println("stack.search(\"刘备\") = " + stack.search("刘备"));
        System.out.println("stack.search(\"关羽\") = " + stack.search("关羽"));
        System.out.println("stack.search(\"张飞\") = " + stack.search("张飞"));
    }

ArrayList 和 LinkedList 的区别

存储结构

  • ArrayList 的底层采用的是以数组为基础存储
  • LinkedList 的底层采用的是链表存储的.

性能

  • ArrayList:增加元素,删除元素,修改元素性能比 LinkedList 慢,读取数据速度快.
  • 链表:增加元素,删除元素,修改元素性能比 ArrayList 快.读取速度慢.

Set集合

  • 描述:无序不可重复的集合。
    默认初始容量 加载因子

HashSet

add不能添加重复元素

@Test
public void testAdd(){
    HashSet<String> set = new HashSet<>();
    set.add("刘备");
    set.add("关羽");
    set.add("张飞");
    System.out.println("set = " + set);
}

add有大坑

  • Set中不能添加重复元素,但是如下情况添加的元素并不是重复元素,添加的元素都是新new出来的对象。
@Test
    public void testAddPerson(){
        HashSet<Person> set = new HashSet<>();
        set.add(new Person("孙权",26));
        set.add(new Person("孙权",26));
        set.add(new Person("孙权",26));
        set.add(new Person("周瑜",23));
        set.add(new Person("周瑜",23));
        }

remove删除()和ArrayList的情况类似

  1. ForEach删除容易出错
  2. 迭代器使用list.remove也不能删除,会报错
  3. 迭代器remove可以删除 iterator.remove

不可重复的集合在调用add方法添加元素时,JVM会调用compareTo方法

重写equals和HashCode方法

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Person)) return false;
        Person person = (Person) o;
        return getAge() == person.getAge() &&
                Objects.equals(getName(), person.getName());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getName(), getAge());
    }

内部比较器

//外部比较器
    @Test
    public void testAddPerson2(){
        TreeSet<Person> set = new TreeSet<>(new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                int i = o1.getAge() - o2.getAge();
                int j = o1.getName().compareTo(o2.getName());
                return i == 0?j:i;
            }
        });
        set.add(new Person("a",50));
        set.add(new Person("b",20));
        set.add(new Person("c",20));
        System.out.println("set = " + set);
    }

外部比较器

@Override
    public int compareTo(Person o) {
        int i = this.getAge() - o.getAge();
        int j = getName().compareTo(o.getName());
        return i == 0?j:i;
    }
    

其他一些需要注意的点

  • 先比较HashCode 如果不同 则通过equals比较
  • 不能使用普通for循环遍历set集合,set集合是无序的。
  • forEach也不能用set.remove删除
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

香鱼嫩虾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值