本文介绍: 原因:每当删除一个元素,下一个元素就会向前顶一个位置,会使原本index为1的元素变为为0,且 i 在执行后会自增,导致一半元素无法删除。但是如果想再向list1中添加元素时会报错,原因是上述写法执行时JVM会自动申请两块(只有两块)连续的内存空间,再add会报错。在第index个位置添加新的值e,原来这个位置及其后面的元素都向后移一位。删除第index数,返回的是被删除的那个数;当List内元素确定时,这样写性能较高,没有扩容操作。2、接口可以被多个类实现吗?1、接口可以被继承吗?

List Set Map

一、List

几个小问题

1、接口可以被继承吗?(可以

2、接口可以被多个类实现吗?(可以)

3、以下两种写法有什么区别?

//List list1=new List();是错误的因为List()是一个接口,是抽象的不能被实例化
//ArrayList()在源码中是一个类(class),可以new对象
//只能用List接口里的方法,不能使用ArrayList中的方法
List list1=new ArrayList();


//可以使用ArrayList里的所有方法,因为ArrayList实现1ist接口,所以可以调用方法比第一种要多,还可以使用List接口里面没有的方法
ArrayList list2=new ArrayList();

4、通常List添加元素:

List<String&gt; list = new ArrayList<&gt;();
list.add("aaa");
list.add("bbb");

当所添加元素确定时,可以这样写:

List<String&gt; list1 = Arrays.asList("aaa","bbb");

当List内元素确定时,这样写性能较高,没有扩容操作

但是如果想再向list1中添加元素时会报错,原因是上述写法执行时JVM会自动申请两块(只有两块)连续的内存空间,再add会报错。

List中的api

1、添加元素 add()
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");

System.out.println(list); //[aaa,bbb,ccc,ddd]
2、获取指定下标元素 get(int index)
String str = list.get(3);
System.out.println(str);//ccc
3、设置指定元素更改为新值 set(int index,E e)
String old = list.set(0, "1");
System.out.println(list);//[1,bbb,ccc,ddd]
System.out.println(old);//aaa
4、指定位置添加新元素 add(int index,E e)

在第index个位置添加新的值e,原来这个位置及其后面的元素都向后移一位。

//list集合为:[aaa,bbb,ccc,ddd]
list.add(1,"2");
System.out.println(list);
//[aaa,2,bbb,ccc,ddd]
5、删除指定位置元素 remove(int index)

删除第index数,返回的是被删除的那个数;每次只能删除一个数

String str = list.remove(1);
System.out.println(list);//[aaa,bbb,ccc,ddd]
System.out.println(str);//2
6、删除全部元素
错误示例遍历删除
List<String> list = new ArrayList<>();
//这里插入4个aaa
list.add("aaa");
list.add("aaa");
list.add("aaa");
list.add("aaa");

//遍历删除
for(int i=0;i<list.size();i++){
    if("aaa".equals(list.get(i))){
        list.remove(i);
    }
}

System.out.println(list); //[aaa,aaa]

0

发现这样的遍历删除并不能删除干净。

为什么遍历list删不干净

原因:每当删除一个元素,下一个元素就会向前顶一个位置,会使原本index为1的元素变为为0,且 i 在执行后会自增,导致一半元素无法删除。

删除的三种方法
  • 倒序删除
public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("aaa");
        list.add("aaa");
        list.add("aaa");

        //倒序遍历删除
        for(int i=list.size()-1;i>=0;i--){
            if("aaa".equals(list.get(i))){
                list.remove(i);
            }
        }
        System.out.println(list);
    }
public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("aaa");
        list.add("aaa");
        list.add("aaa");

        // 使用迭代器删除
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()) {
            String s = iterator.next();
            if ("aaa".equals(s)) {
                iterator.remove();
            }
        }
        System.out.println(list);
    }
  • lambada删除
public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("aaa");
        list.add("aaa");
        list.add("aaa");

        // 使用 jdk8 新方法
        list.removeIf(item -> "aaa".equals(item));
        System.out.println(list);
    }

list判空?
List<String> list=new ArrayList<>();
system.out.print(list==null); //false

list数组是new出来的,判断一定为false

使用 hutool 工具类判空

依赖

<!--hutool工具类-->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.11</version>
</dependency>

工具类判空

List<String> list = new ArrayList<>();

//写法错误,当list定义为List<String> list=null;会出现空指针
list.get(1).equals(list.get(2));

//正确写法
boolean equals=StrUtils.equals(list.get(1),list.get(2));

list不是线程安全

    1)继承Thread创建线程

    2)实现Runnable接口创建线程

    3)使用Callable和Future创建线程

    4)使用线程池例如用Executor框架

public class ListDemo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();

        MyThread m1=new MyThread(list);
        MyThread m2=new MyThread(list);
        new Thread(m1).start();
        new Thread(m2).start();


        System.out.println(list);
    }
}
public class MyThread implements Runnable{
    ArrayList<String> arr;

    public MyThread(ArrayList<String> arr) {
        this.arr = arr;
    }

    @Override
    public void run() {
        for(int i=0;i<100;i++){
            arr.add("arr"+i);
            System.out.println(Thread.currentThread().getName()+"在第"+i+arr.get(i));
        }
    }
}

0

两个线程操作同一个List导致线程不安全

原文地址:https://blog.csdn.net/m0_61982496/article/details/134637315

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_4121.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注