【问题标题】:Why removeRange method of ArrayList class is not working? [duplicate]为什么 ArrayList 类的 removeRange 方法不起作用? [复制]
【发布时间】:2014-01-11 23:38:53
【问题描述】:

我正在尝试使用removeRange 方法从ArrayList 中删除某些元素。我从这里了解了这个方法:http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#removeRange(int, int)

但是当我这样尝试时

ArrayList<String> al = new ArrayList<String>();
al.add("AB");
al.add("BC");
al.add("CD");
al.add("DE");
al.removeRange(1, 3);

我收到了这个错误:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
The method removeRange(int, int) from the type ArrayList<String> is not visible

为什么我不能使用这种方法?我做错了吗?

【问题讨论】:

    标签: java arraylist


    【解决方案1】:

    简短的回答是:使用

    al.subList(1, 3).clear();
    

    removeRange(int, int) 方法是protected。您只能从ArrayList 的子类或从与ArrayList 相同的包中的类调用它。见Controlling Access to Members of a Class

    访问removeRange 方法的唯一方法是继承ArrayList 并将该方法公开。例如

    public class RangeRemoveSupport<E> extends ArrayList<E> {
    
      public void removeRange(int fromIndex, int toIndex) {
        super.removeRange(fromIndex, toIndex);
      }
    
    }
    

    但是你的代码必须使用子类。因此,您的代码依赖于这个子类,而不仅仅是依赖于 ListArrayList

    同一包中的实用程序类无法访问它。例如

    package java.util; // <- SecurityException
    
    public class RemoveRangeSupport {
    
        public static void removeRange(ArrayList<?> list, int from, int to){
           list.removeRange(from, to);
        }
    }
    

    这将导致SecurityException

    java.lang.SecurityException: Prohibited package name: java.util.

    因为出于安全原因,您不能在java.util 中定义类。

    不过对于其他软件包来说,这可能是一种方式。

    我经常使用这种策略进行测试。然后我将这样一个实用程序类与生产代码放在同一个包中,以从通常无法访问的测试中访问一些内部结构。这是一种不使用框架的简单方法。

    编辑

    是否有一个函数可以将 X..Y 范围内的项目替换为可能不同大小的新项目?

    例如:此列表“0,1,2,3,4”,我将 1..3 替换为“a,b,c,d,e”,结果为:“0,a,b ,c,d,e,4"。

    List<String> list = new ArrayList<>(Arrays.asList("0", "1", "2", "3", "4"));
    List<String> subList = list.subList(1, 4);
    subList.clear();
    subList.addAll(Arrays.asList("a", "b", "c", "d", "e"));
    System.out.println(list);
    

    会输出

    [0, a, b, c, d, e, 4]
    

    【讨论】:

    • 是否有一个功能可以将 X..Y 范围内的项目替换为可能不同大小的新项目?例如:这个列表“0,1,2,3,4”,我将 1..3 替换为“a,b,c,d,e”,结果为:“0,a,b,c, d,e,4"。
    • @androiddeveloper 是的,我更新了答案
    • 不错。但是,它不会导致细胞移动两次吗?我在这里提出了一个新问题:stackoverflow.com/q/47416833/878126
    【解决方案2】:

    由于它是一个受保护的方法,它只对类、包和子类可见。

    protected 修饰符指定该成员只能在其自己的包中访问(与 package-private 一样),此外,它的类在另一个包中的子类也可以访问。

    Modifier    Class   Package Subclass    World
    ---------------------------------------------
    public      Y      Y        Y           Y
    protected   Y      Y        Y           N
    no modifier Y      Y        N           N
    private     Y      N        N           N
    

    http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

    【讨论】:

    • 嘿 Suresh,感谢您的回答,但是如何从 ArrayList 中删除某些指定范围的元素?
    • 不,你不能。一次您可以删除一个元素,循环删除或查看 sublist() 方法。这可能有用。
    • 很高兴,它有帮助。查看 removeRange 方法的源代码,看看他们在做什么。这会引发一些想法。
    • 或者你可以扩展 ArrayList 并公开它。但它受到保护可能有充分的理由。
    【解决方案3】:

    你可以使用:a1.subList(1, 3).clear(); 这里已经讨论过了:Why is Java's AbstractList's removeRange() method protected? 它可能会帮助您更好地理解。

    【讨论】:

      【解决方案4】:

      removeRange(int firstIndex, int lastIndex) 方法是ArrayList&lt;Object&gt; 中的protected 方法。受保护的方法可以在类、子类和包中访问,但不是公共的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-29
        • 1970-01-01
        • 2014-10-26
        • 2020-01-09
        • 2023-03-26
        • 1970-01-01
        相关资源
        最近更新 更多