【问题标题】:Implement own ArrayList<> without using collections实现自己的 ArrayList<> 而不使用集合
【发布时间】:2014-05-10 05:44:18
【问题描述】:

我正在尝试实现我自己的 ArrayList 而不使用 java 集合进行练习。在这个阶段,我想实现两个主要方法,add(E) 和 get(int) tp 得到这个想法。我的代码如下。但是我遇到了一些问题:

  1. “return (E) myData[index]”行发出警告“类型安全:从 Object 到 E 的未经检查的强制转换”。我该如何解决这个问题
  2. ArrayList.add(T) 的 Java 7 实现返回一个布尔值。在什么情况下 add() 必须返回 false。在什么逻辑下返回false,什么时候返回true?
  3. 在哪里可以找到 ArrayList 的 java 7 实现的源代码

PS。请不要只回答问题 3 并让我参考 1 和 2 的蔗糖代码!

import java.util.Arrays;

public class MyArrayList<E>{
    private final int DEFAULT_SIZE=2;
    private Object[] myData = new Object[DEFAULT_SIZE];
    private int actSize=0;

    public boolean add(E data){
        if (actSize>=myData.length/2){
            increaseSize();
        }
        myData[actSize++] = data;
        return true;//when can it be false?
    }

    private void increaseSize()throws RuntimeException{
        myData = Arrays.copyOf(myData, myData.length*2);
    }

    public E get(int index) throws RuntimeException{
        if (index >= actSize){
            throw new IndexOutOfBoundsException(); 
        }
        return (E) myData[index];
    }

    public static void main(String[] args) {
        MyArrayList<String> arList = new MyArrayList<>();
        arList.add("Hello");
        arList.add("Bye bye!");
        System.out.println(arList.get(1));// prints Bye bye! which is correct

    }
}

【问题讨论】:

标签: java collections arraylist


【解决方案1】:

我在cmets中很少做解释,因为很清楚。

public class MyArrayList<E extends Object> {

    private static int initialCapacity = 5;
    private static int currentSize;
    private Object[] myArrayList = {}, temp = {};

    private static int currentIndex = 0;

    public static void main(String[] args) {
        MyArrayList arrList = new MyArrayList();
        arrList.add("123"); //add String
        arrList.printAllElements();
        arrList.add(new Integer(111)); //add Integer
        arrList.printAllElements();

        arrList.add(new Float("34.56")); //add Integer
        arrList.printAllElements();

        arrList.delete("123");
        arrList.printAllElements();

        arrList.delete(123);
        arrList.printAllElements();
        arrList.delete(123);

        arrList.printAllElements();

    }

    public MyArrayList() {  //creates default sized Array of Objects
        myArrayList = new Object[initialCapacity]; //generic expression

        /* everytime I cross my capacity, 
    I make double size of Object Array, copy all the elements from past myObject Array Object
         */
    }

    public MyArrayList(int size) { //creates custom sized Array of Objects
        myArrayList = new Object[size];
    }

    public void add(Object anyObj) {
        //add element directy
        myArrayList[currentIndex] = anyObj;
        currentSize = myArrayList.length;
        currentIndex++;
        if (currentIndex == currentSize) {
            createDoubleSizedObjectArray(currentSize);
        }
    }

    //print all elements
    public void printAllElements() {
        System.out.println("Displaying list : ");
        for (int i = 0; i < currentIndex; i++) {
            System.out.println(myArrayList[i].toString()); 
        }
    }

    private void createDoubleSizedObjectArray(int currentSize) {
        temp = myArrayList.clone();
        myArrayList = new MyArrayList[2 * currentSize];  //myObject pointer big size data structure

//         myObject = temp.clone(); //probably I can do this here as well. Need to check this
        System.arraycopy(temp, 0, myArrayList, 0, currentSize);

    }

    void delete(Object object) {
        //if already empty 
        if (currentIndex == 0) {
            System.out.println("Already empty!");
            return;
        }
        //you don't need to delete anything. I can simply override the storage
        currentIndex--;
    }
}

【讨论】:

  • 这不能回答任何 OP 的问题。
【解决方案2】:

“return (E) myData[index]”行发出警告“类型安全:从对象到 E 的未经检查的强制转换”。我该如何解决这个问题?

您总是会收到这个未经检查的强制转换警告,因为您使用的是通用数组。泛型和数组don't really mix 都很好,但更好的约定是将泛型类型附加到数组:

private E[] myData = (E[]) new Object[DEFAULT_SIZE];

您始终可以将@SuppressWarnings("unchecked") 添加到字段本身以消除该警告。

@SuppressWarnings("unchecked")
private E[] myData = (E[]) new Object[DEFAULT_SIZE];

ArrayList.add(T) 的 Java 7 实现返回一个布尔值。在什么情况下 add() 必须返回 false。在什么逻辑下返回false,什么时候返回true?

这是一个有趣的问题。通常,人们会认为对add 的限制来自Collections#add

支持此操作的集合可能会限制可以添加到此集合的元素。特别是,一些集合会拒绝添加空元素,而另一些则会对可能添加的元素类型施加限制。集合类应在其文档中明确指定对可以添加哪些元素的任何限制。

...但是,由于ArrayList 的特殊之处在于它的设计总是在即将用完时扩展其空间,因此它(理论上)总是能够在其中添加一些东西. 所以,它应该总是返回true

在哪里可以找到 ArrayList 的 Java 7 实现的源代码?

Grepcode 通常是一个很好的资源。如果你下载了带有源的 JDK,你也可以在 src.zip 中找到它。

【讨论】:

    【解决方案3】:
    1. 我认为您无法使用泛型类型避免该类型安全警告。如果实在困扰你,可以加@SupressWarnings("unchecked")
    2. 嗯,我不确定这个,但不完全相同的 Java 的 Android 实现说它“总是返回 true”。这对我来说很奇怪,但这是链接:http://developer.android.com/reference/java/util/ArrayList.html#add(E)
    3. http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java,但一定要下载源代码并查看。

    【讨论】:

      【解决方案4】:

      “return (E) myData[index]”行发出警告“类型安全: 从对象到 E 的未经检查的强制转换”。我该如何解决这个问题

      抑制警告

      @SuppressWarnings("unchecked")
      

      ArrayList.add(T) 的 Java 7 实现返回 boolean。 在什么情况下add() 必须返回false。根据什么 逻辑它返回false,什么时候返回true

      javadoc

      返回true(由Collection.add(E)指定)

      它总是返回true

      哪里可以找到java 7实现ArrayList的源码

      在您的 JDK 安装的 src.zip 存档中或通过简单的搜索在线找到它

      java ArrayList 源码

      【讨论】:

      • @nachokk 在大多数情况下,创建一个通用数组比它的价值更麻烦。
      • @nachokk 他们可以,但是创建一个通用数组也很麻烦。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-21
      • 2011-06-07
      • 2015-10-05
      • 2011-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多