简体   繁体   English

如何在使用 ArrayList 的“removeRange”方法时使用泛型来实现类型安全

[英]How to use generics for type safety while using `removeRange` method of ArrayList

Since the method - removeRange(int startIndex, int ) is protected, we need to use it in a class extending ArrayList.由于方法 - removeRange(int startIndex, int )是受保护的,我们需要在扩展 ArrayList 的类中使用它。 Below is my code -下面是我的代码 -

public class MyClass extends ArrayList<String> {

    public static void main(String[] args) {
        MyClass arrayList1 = new MyClass();
        arrayList1.add("Zebra");
        arrayList1.add("Giraffe");
        arrayList1.add("Bison");
        arrayList1.add("Hippo");
        arrayList1.add("Elephant");

        MyClass arrayList2 = (MyClass) arrayList1.clone();
        MyClass arrayList3 = (MyClass) arrayList1.clone();

        System.out.println(arrayList1);
        System.out.println(arrayList2);
        System.out.println(arrayList3);

        arrayList1.removeRange(0, 3);
        arrayList2.removeRange(3, 5);
        arrayList3.removeRange(2, 4);

        System.out.println(arrayList1);
        System.out.println(arrayList2);
        System.out.println(arrayList3);
    }
}

Output -输出 -

[Zebra, Giraffe, Bison, Hippo, Elephant]
[Zebra, Giraffe, Bison, Hippo, Elephant]
[Zebra, Giraffe, Bison, Hippo, Elephant]
[Hippo, Elephant]
[Zebra, Giraffe, Bison]
[Zebra, Giraffe, Elephant]

Now to use type safety I need to write - MyClass<String> extends ArrayList<String> but doing so gives error in main method of String[] -现在要使用类型安全,我需要编写 - MyClass<String> extends ArrayList<String>但这样做会在String[]的主要方法中产生错误 -

MyClass.This cannot be referenced from a static context

So how is it possible to use generics in removeRange method of ArrayList?那么如何在 ArrayList 的removeRange方法中使用generics呢?

Your premise:你的前提:

Since the method - removeRange(int startIndex, int ) is protected, we need to use it in a class extending ArrayList.由于方法 - removeRange(int startIndex, int) 是受保护的,我们需要在扩展 ArrayList 的类中使用它。

… is incorrect. … 是不正确的。

👉 removeRange is not meant to be called from outside the class. 👉 removeRange并不意味着从类外调用。 So no need to create your subclass.所以不需要创建你的子类。

Instead, call List#subList and List#clear .相反,请调用List#subListList#clear

list.subList( start , end ).clear() ;

See the Javadoc for AbstractList#removeRange :请参阅AbstractList#removeRange的 Javadoc:

This method is called by the clear operation on this list and its subLists.此方法由对该列表及其子列表的clear操作调用。

See Item 40 of Effective Java 2nd ed.请参阅Effective Java第 2 版的第 40 项。

See discussion in this post .请参阅这篇文章中的讨论。

Example code:示例代码:

List< String > original = List.of( "Zebra" , "Giraffe", "Bison", "Hippo", "Elephant" ) ;

ArrayList< String > a1 = new ArrayList <> ( original ) ;
ArrayList< String > a2 = new ArrayList <> ( original ) ;
ArrayList< String > a3 = new ArrayList <> ( original ) ;

a1.subList( 0, 3 ).clear() ;
a2.subList( 3, 5 ).clear() ;
a3.subList( 2, 4 ).clear() ;

System.out.println( a1 );
System.out.println( a2 );
System.out.println( a3 );

See this code run live at IdeOne.com .请参阅在 IdeOne.com 上实时运行的代码

[Hippo, Elephant]
[Zebra, Giraffe, Bison]
[Zebra, Giraffe, Elephant]

The way to make MyClass able to store objects of any type, not just String is to introduce a type parameter T which fills in for the type.MyClass能够存储任何类型的对象,而不仅仅是String的方法是引入一个类型参数T来填充类型。 The declaration will then be然后声明将是

public class MyClass<T> extends ArrayList<T>

But then, you have to specify what T is when you declare a MyClass variable.但是,您必须在声明MyClass变量时指定T是什么。 This means you'll need to change your variable declarations and initialisations to things like这意味着您需要将变量声明和初始化更改为

MyClass<String> arrayList1 = new MyClass<>();

which tells the compiler what type to use in place of T .它告诉编译器使用什么类型代替T

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM