如何在使用 ArrayList 的“removeRange”方法时使用泛型来实现类型安全
How to use generics for type safety while using `removeRange` method of ArrayList
由于方法 - removeRange(int startIndex, int )
受到保护,我们需要在 class 扩展 ArrayList 中使用它。下面是我的代码 -
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);
}
}
输出-
[Zebra, Giraffe, Bison, Hippo, Elephant]
[Zebra, Giraffe, Bison, Hippo, Elephant]
[Zebra, Giraffe, Bison, Hippo, Elephant]
[Hippo, Elephant]
[Zebra, Giraffe, Bison]
[Zebra, Giraffe, Elephant]
现在要使用类型安全,我需要写 - MyClass<String> extends ArrayList<String>
但这样做会在 String[]
-
的主要方法中出错
MyClass.This cannot be referenced from a static context
那么如何在ArrayList的removeRange
方法中使用generics
呢?
你的前提:
Since the method - removeRange(int startIndex, int ) is protected, we need to use it in a class extending ArrayList.
…不正确。
removeRange
并不意味着要从 class 外部调用。所以不需要创建你的 subclass.
而是调用 List#subList
and List#clear
。
list.subList( start , end ).clear() ;
请参阅 AbstractList#removeRange
的 Javadoc:
This method is called by the clear
operation on this list and its subLists.
参见 Effective Java 第二版的第 40 项。
参见 this post 中的讨论。
示例代码:
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 );
看到这个code run live at IdeOne.com。
[Hippo, Elephant]
[Zebra, Giraffe, Bison]
[Zebra, Giraffe, Elephant]
使 MyClass
能够存储任何类型的对象,而不仅仅是 String
的方法是引入一个 类型参数 T
填充类型。声明将是
public class MyClass<T> extends ArrayList<T>
但是,当您声明一个 MyClass
变量时,您必须指定 T
是什么。这意味着您需要将变量声明和初始化更改为
MyClass<String> arrayList1 = new MyClass<>();
告诉编译器使用什么类型来代替 T
。
由于方法 - removeRange(int startIndex, int )
受到保护,我们需要在 class 扩展 ArrayList 中使用它。下面是我的代码 -
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);
}
}
输出-
[Zebra, Giraffe, Bison, Hippo, Elephant]
[Zebra, Giraffe, Bison, Hippo, Elephant]
[Zebra, Giraffe, Bison, Hippo, Elephant]
[Hippo, Elephant]
[Zebra, Giraffe, Bison]
[Zebra, Giraffe, Elephant]
现在要使用类型安全,我需要写 - MyClass<String> extends ArrayList<String>
但这样做会在 String[]
-
MyClass.This cannot be referenced from a static context
那么如何在ArrayList的removeRange
方法中使用generics
呢?
你的前提:
Since the method - removeRange(int startIndex, int ) is protected, we need to use it in a class extending ArrayList.
…不正确。
removeRange
并不意味着要从 class 外部调用。所以不需要创建你的 subclass.
而是调用 List#subList
and List#clear
。
list.subList( start , end ).clear() ;
请参阅 AbstractList#removeRange
的 Javadoc:
This method is called by the
clear
operation on this list and its subLists.
参见 Effective Java 第二版的第 40 项。
参见 this post 中的讨论。
示例代码:
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 );
看到这个code run live at IdeOne.com。
[Hippo, Elephant]
[Zebra, Giraffe, Bison]
[Zebra, Giraffe, Elephant]
使 MyClass
能够存储任何类型的对象,而不仅仅是 String
的方法是引入一个 类型参数 T
填充类型。声明将是
public class MyClass<T> extends ArrayList<T>
但是,当您声明一个 MyClass
变量时,您必须指定 T
是什么。这意味着您需要将变量声明和初始化更改为
MyClass<String> arrayList1 = new MyClass<>();
告诉编译器使用什么类型来代替 T
。