精华内容
下载资源
问答
  • .pop()是删除list指定位置元素,然后返回被删除的元素值。默认删除最后一个

    .pop()是删除list中指定位置元素,然后返回被删除的元素值。默认删除最后一个

    展开全文
  • List删除指定元素 在List类中,提供了删除元素的remove()方法,有如下两种传参方式 1.根据index删除,会删除指定位置元素,源码如下 public E remove(int index) { try { ListIterator<E> e = ...

     List删除指定元素

    在List类中,提供了删除元素的remove()方法,有如下两种传参方式

        1.根据index删除,会删除指定位置的元素,源码如下

    public E remove(int index) {
        try {
            ListIterator<E> e = listIterator(index);
            E outCast = e.next();
            e.remove();
            return outCast;
        } catch (NoSuchElementException exc) {
            throw new IndexOutOfBoundsException("Index: "+index);
        }
    }

        2.根据对象删除 ,源码如下,该方法使用equals方法判断是否为要删除的对象,经测试,使用list.remove(object)方法后,仅删除集合中第一个满足条件的元素

    public boolean remove(Object o) {
        Iterator<E> it = iterator();
        if (o==null) {
            while (it.hasNext()) {
                if (it.next()==null) {
                    it.remove();
                    return true;
                }
            }
        } else {
            while (it.hasNext()) {
                if (o.equals(it.next())) {
                    it.remove();
                    return true;
                }
            }
        }
        return false;
    }

    根据上述提到的两种方法,可以对List中元素进行删除,但是当需要删除的元素不止一个时,需要循环删除元素,就会产生一些问题

        1.采用for循环由小到大删除时,采用remove(int index)方法,会出现指针越界异常。因为移除List中的一个元素后,List长度会减少,但for循环的次数仍是原本List的长度

    for(int i = 0,j = numberList.size();i < j;i++){
                if(numberList.get(i).equals(element)){
                    numberList.remove(element);
                }
            }
    
    //异常如下
    Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 11, Size: 10
    	at java.util.LinkedList.checkElementIndex(LinkedList.java:555)
    	at java.util.LinkedList.get(LinkedList.java:476)
    	at com.Test.ListTest.main(ListTest.java:29)

        2.当使用Iterator迭代器或是增强for循环遍历数组时,采用remove(Objec o)移除元素时,仍然会出现异常。因为执行 该方法后,对 list 对象的 modCount 值进行了修改,而 list 对象的迭代器的 expectedModCount 值未进行修改

    for(Long l : numberList){
                if(l.equals(element)){
                    numberList.remove(element);
                }
            }
     Iterator iterator = numberList.iterator();
            while (iterator.hasNext()){
                if(iterator.next().equals(element)){
                    numberList.remove(element);
                }
            }
    //异常如下
    Exception in thread "main" java.util.ConcurrentModificationException
    	at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:966)
    	at java.util.LinkedList$ListItr.next(LinkedList.java:888)
    	at com.Test.ListTest.main(ListTest.java:22)

    正确的删除方式有三种:

       1.正序for循环删除,由于删除后List中的元素会前移一位,所以我们首先i--将指针移到被前移的元素上,再将数组长度-1,防止指针越界

            for(int i = 0,j = numberList.size();i < j;i++){
                if(numberList.get(i).equals(element)){
                    numberList.remove(element);
                    j--;
                    i--;
                }
          

        2.倒序for循环删除,List由最后一位向前循环,每次移除元素,指针都会前移一位,总移动次数也与数组长度相同

            for(int i= numberList.size()-1;i >= 0;i--){
                if(numberList.get(i).equals(element)){
                    numberList.remove(element);
                }
            }

    3.迭代器删除,该方法与错误迭代器方法的不同就是需要采用迭代器的remove()方法,而不是List中的remove(Object o)方法

            Iterator iterator = numberList.iterator();
            while (iterator.hasNext()){
                if(iterator.next().equals(element)){
                    iterator.remove();
                }
            }

    List删除与另一List相同元素的方法

        上面说完了简单情况下的List循环删除,实际开发中情况可能更为复杂,需要根据两集合中,元素同名同类型属性值相同,去移除其中一个集合中的元素

        1.有集合a和集合b,现在需要将a从移除a与b的子集,如果集合中的元素可以用"=="或者"equals()"方法判定是否相同,那么可以使用List中提供的removeAll(Collection c)方法,该方法可以将a中的a与b子集含有的元素全部删除,缺点是执行效率较低

            //生成1-100的随机数,集合a
            List<Long> numberList = new LinkedList<>();
            for(int i = 0 ; i < 10 ; i++){
                numberList.add((long)(Math.random()*100+1));
                numberList.add(10L);
            }
    
            Long element = 10L;
    
            //集合b
            List<Long> targetList = new LinkedList<Long>();
            targetList.add(element);
    
            numberList.removeAll(targetList);
            System.out.println(numberList);

        2.当情况更为复杂,无法使用equals()方法判断两元素是否相同,或者根据两元素各自的某项属性值判断是否需要移除时,则需要使用双重循环,逐条进行对比,为防止指针越界异常,当移除了元素后,需调整指针位置和循环次数。此处我使用倒序删除的方式,可以避免手动移动指针。值得注意的是:内层循环每次判断元素属性值相同,做移除操作后,必须中断循环,这样指针前移后,又重新循环集合b,避免漏删和空指针的情况。

    for(int i = heroes.size()-1;i >= 0;i--){
                for(int j = idols.size()-1;j >=0;j--){
                    if(heroes.get(i).getBrave() == idols.get(j).getBrave()){
                        heroes.remove(i);
                        break;
                    }
                }
            }
    
    //执行结果如下
    集合a:
    [Name:tom  Brave100, Name:tony  Brave50, Name:tony  Brave20, Name:tom  Brave100, Name:tony  Brave50, Name:tony  Brave20]
    集合b:
    [Name:kk  Brave20, Name:kk  Brave20, Name:cc  Brave50]
    删除后的集合a:
    [Name:tom  Brave100, Name:tom  Brave100]

       3.迭代器实现的方法,运行结果和上面for循环方法的结果相同,缺点是必须使用引用指向强转后的iterator.next(),优点是不用思考指针如何移动

            while (heroeIterator.hasNext()){
                while (idolIterator.hasNext()){
                    Hero h = (Hero)heroeIterator.next();
                    Idol i = (Idol)idolIterator.next();
                    if(h.getBrave() == i.getBrave()){
                        heroeIterator.remove();
                    }
                }
            }
    

     

    展开全文
  • 容器-ListedList删除指定位置元素的源码分析(十一) 根据索引删除元素 import java.util.LinkedList; import java.util.List; public class LinkedListTest { public static void main(String[] args) { List<...

    容器-ListedList删除指定位置元素的源码分析(十一)

    1. 根据索引删除元素

      import java.util.LinkedList;
      import java.util.List;
      
      public class LinkedListTest {
          public static void main(String[] args) {
              List<String> list= new LinkedList<>();
              //添加元素
              list.add("a");
              list.add("b");
              list.add("c");
              list.add("a");
              list.add(2,"aaaa");
              
              //根据索引删除元素
              list.remove(2);
              ]
          }
      
    2. 看remove的源代码,先Ctrl进去

          E remove(int index);
      
      • 在用Ctrl+Alt选择remove方法的LinkedList接口实现类

        /**
             * Removes the element at the specified position in this list.  Shifts any
             * subsequent elements to the left (subtracts one from their indices).
             * Returns the element that was removed from the list.
             *
             * @param index the index of the element to be removed
             * @return the element previously at the specified position
             * @throws IndexOutOfBoundsException {@inheritDoc}
             */
            public E remove(int index) {
                checkElementIndex(index);//校验索引是否正常
                return unlink(node(index));
            }
        
      • 我们看 checkElementIndex(index);方法

            private void checkElementIndex(int index) {
                if (!isElementIndex(index))
                    throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
                //如果isPositionIndex返回的是true,再取非,则不执行if条件语句,证明索引没问题
                //如果isPositionIndex返回的是false,再取非,则执行if条件语句,抛出异常
            }
        
      • 在进去看isElementIndex(index)

          /**
             * Tells if the argument is the index of an existing element.
             */
            private boolean isElementIndex(int index) {
                return index >= 0 && index < size;//注意这里的是索引要小于元素的个数,不能取等于,因为索引的个数是要比元素的个数少一个数的
            }
        
      • 当校验索引没有问题,就要看 unlink方法了,里面还有个node的方法。

            public E remove(int index) {
                checkElementIndex(index);//校验索引是否正常
                return unlink(node(index));
            }
        
      • 先看node方法

          /**
             * Returns the (non-null) Node at the specified element index.
             */
            Node<E> node(int index) {
                // assert isElementIndex(index);
        
                if (index < (size >> 1)) {
                    Node<E> x = first;
                    for (int i = 0; i < index; i++)
                        x = x.next;
                    return x;
                } else {
                    Node<E> x = last;
                    for (int i = size - 1; i > index; i--)
                        x = x.prev;
                    return x;
                }
            }
        
        
      • node的原理图
        在这里插入图片描述

      • 然后我们回去看 unlink方法,假设我们现在删除的是索引为2的节点,也就是删除已33为地址的节点。

        /**
             * Unlinks non-null node x.
             */
            E unlink(Node<E> x) {
                // assert x != null;
                final E element = x.item;//就是那个被删除的节点返回回去
                final Node<E> next = x.next;
                final Node<E> prev = x.prev;
        
                if (prev == null) {//删除的是头节点才会用到
                    first = next;
                } else {//假设我们现在删除的是索引为2的节点
                    prev.next = next;
                    x.prev = null;
                }
        
                if (next == null) {//删除的是最后一个节点,显然现在不是,我们走else
                    last = prev;
                } else {
                    next.prev = prev;
                    x.next = null;
                }
        
                x.item = null;//把33节点制为空,
                size--;//元素被删掉一个,被减一个
                modCount++;
                return element;//就是返回那个被删除的节点
            }
        
        
      • unlink方法,也就是删除指定元素的关键方法,就是把要删除的那个节点的两边的节点,想办法断开,在引用到两边的节点。原理图:
        在这里插入图片描述

    展开全文
  • 1、使用原始for循环 for(int i =0 ;...intList.size() ; i++){ if(intList.het(i) == 13){ intList.remove(i); i--; } } 2、使用迭代器(官方推荐) Iterator<Integer> it = intList....
    1、使用原始for循环
    for(int i =0 ; i<intList.size() ; i++){
        if(intList.het(i) == 13){
            intList.remove(i);
            i--;
        }
    }
     
    2、使用迭代器(官方推荐)
    Iterator<Integer> it = intList.iterator();
    where(it.hasNext()){
        if(it.next() == 13){
            it.remove();
        }
    }
     
    用这两个方法才不会出现空指针。
    我们撸代码过程中就是因为有很多这样的小问题没有积累下来,才使得工作效率低了很多!所以一定要积累啊!
     
    如果文章对你有帮助,麻烦帮忙点个赞哦!嘿嘿!做一个靠谱的技术博主!
     

    转载于:https://www.cnblogs.com/CatcherLJ/p/11201680.html

    展开全文
  • 给定一个python的list对象,想要删除其中指定几个下标所在位置元素,有什么好的解决方案? e.g. >>> list_given = [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> index_to_delete = [1, 3, 6] &g
  • js数组是js部分非常重要的知识,有时我们有这么个需求js数组删除指定元素,先定义一个函数来获取删除指定元素索引值,然后用js数组删除的方法,来删除指定元素即可,就两步不难,很简单。1、JS的数组对象定义一个...
  • 采用C语言实现:完整删除链表中指定位置元素的代码。 原链表:3->4->5。现在要删除位置为2处的元素删除后的链表:3->5。 #include <stdio.h> #include <stdlib.h> #include <MacTypes...
  • package day04; import java.util.ArrayList; import java.util.List; /** * List集合提供了一对重载的add/remove方法 * void add(int index,E e) ... * 从集合中删除指定位置元素,并将其返回。 * ...
  • public Item delete(int k){ if(isEmpty()) ...List is empty"); int i = 1; Node prev = null, curr = first; if(size() &gt;= k){ while(i &lt; k){ prev = curr; ...
  • 在Python中,调用del函数能够删除指定索引位置元素,其基本语法如下: del source_list[index] 其中, source_list:为待修改的列表 index:为待删除元素位置索引 例如,将请客名单guests列表中的Zhang san删除...
  • 一维列表 a=[1,2,3,4] a.pop()#删除最后一位 print(a) 输出: [1, 2, 3] 二维列表 a=[[1,2],[2,3],[1,2],[1,2]...那么,如果要删除某一位的元素呢? a=[1,2,3,4] del a[-2]#删除倒数第二位 print(a) 输出: [1, 2, 4

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 968
精华内容 387
关键字:

list删除指定位置元素