对象的Java数组行为奇怪吗?

时间:2017-05-31 12:04:12

标签: java arrays object

我如何看待我的问题,请告诉我哪里出错了?干杯

Book[] booksArray = new Book[10];
Book[] sortedBooks = new Book[10];

2个不同的图书对象数组,对吗? (假设他们有数据,cbf发布所有代码)

sortedBooks = booksArray;

sortedBooks现在是booksArray的副本,是吗?

sortBooksByPrice(sortedBooks, numOfBooks);

public static void sortBooksByPrice(Book[] sortedBooks, int numOfBooks)
    {
        Book objHolder;//For the purpose of swapping/sorting

        for(int i = 0; i < numOfBooks; i++)   
        {
            if(numOfBooks > (i +1))
            {
                if(Double.parseDouble(sortedBooks[i].getPrice()) > 
                    Double.parseDouble(sortedBooks[i+1].getPrice()))
                {
                    objHolder = sortedBooks[i];
                    sortedBooks[i] = sortedBooks[i+1];
                    sortedBooks[i+1] = objHolder;
                }
            }
        }
            displayAllBooks(sortedBooks, numOfBooks);
    }

按预期显示sortedBooks,但现在如果我调用

displayAllBooks(booksArray , numOfBooks);

它将显示sortedBooks。这里发生了什么? d:

7 个答案:

答案 0 :(得分:1)

魔术发生在这一行:

sortedBooks = booksArray;

您没有复制booksArray。真正发生的是你正在sortedBooks引用booksArray指的同一个数组。

这意味着没有创建新数组。你只有2个名字引用同一个东西。这就是为什么在您对sortedBooks进行更改后,更改也会发生在booksArray

如果您想真正复制数组,可以使用for循环手动将元素从一个数组复制到另一个数组:

for (int i = 0 ; i < booksArray.length ; i++) {
    sortedBooks[i] = booksArray[i];
}

或使用copyOf方法:

sortedBooks = Arrays.copyOf(booksArray, booksArray.length);

答案 1 :(得分:1)

当你这样做时:

sortedBooks = booksArray;

您的sortedBooks变量将指向booksArray,而不是克隆该对象。

您可以使用Java Comparable界面获得更好的结果:

class BookPriceComparator implements Comparator<Book> {

    @Override
    public int compare(Book b1, Book b2) {
        return b1.getPrice().compareTo(b2.getPrice());
    }
}

然后:

Arrays.sort(booksArray, new BookPriceComparator());

希望它有所帮助。

答案 2 :(得分:0)

  
    

sortedBooks现在是booksArray的副本,是吗?

  

没有。 sortedBooks points to booksArray。你只有两个链接到一个数组。

答案 3 :(得分:0)

为什么不实施比较器来进行比较(BookComaparator) 然后致电:

Arrays.sort(sortedBookks,new BookComaparator);

答案 4 :(得分:0)

  

sortedBooks现在是booksArray的副本,是吗?

其实没有。因为您刚刚对sortedBooks引用的同一数组对象重新分配了booksArray引用。 因此,您有两个对一个数组对象的引用。第二个有资格进行垃圾收集。

答案 5 :(得分:0)

是的,这是一个经典的Java原则。正如这里提到的https://en.wikipedia.org/wiki/Clone_(Java_method)

  

在Java中,对象通过引用变量进行操作,并且没有用于复制对象的运算符 - 赋值运算符复制引用,而不是对象。 clone()方法提供了这个缺少的功能。

初始化2个数组时,每个对象都指向堆上的某个内存位置。让我们说booksArray指向一个具有内存位置X的对象,sortedBooks指向一个内存位置为Y的对象。

现在你做了

sortedBooks = booksArray

你基本上指出sortedBooks的内存引用指向booksArray的内存位置是Y.简而言之,booksArray和sortedBooks现在指向堆上的同一个对象。

对sortedBooks进行的任何操作都将更改sortedBooks指向的对象中的数据。由于booksArray指向同一个对象,它也会反映出相同的变化。

如果要在java中深层复制对象,请使用Object.clone()方法 详情请访问https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#clone()

答案 6 :(得分:-1)

sortedBooks = Arrays.copyOf(booksArray, booksArray.length);