有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java对象数组行为异常?

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

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

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

sortedBooks = booksArray;

sortedBooks现在是BookArray的副本,是吗

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);

它将显示已分类的书籍。这是怎么回事?D:


共 (6) 个答案

  1. # 1 楼答案

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

    In Java, objects are manipulated through reference variables, and there is no operator for copying an object—the assignment operator duplicates the reference, not the object. The clone() method provides this missing functionality.

    初始化2个数组时,每个对象都指向堆上的某个内存位置。假设booksArray指向内存位置为X的对象,sortedBooks指向内存位置为Y的对象

    现在当你这么做的时候

    sortedBooks=Books数组

    实际上,您将sortedBooks的内存引用指向BookArray的内存位置,即Y。简而言之,BookArray和sortedBooks现在指向堆上的同一个对象

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

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

  2. # 2 楼答案

    sortedBooks is now a duplicate of booksArray, yes?

    编号。已分拣的书籍指向书籍阵列的点。一个数组只有两个链接

  3. # 3 楼答案

    为什么不实现一个比较器来进行比较(BookComaparator) 然后打电话:

    Arrays.sort(sortedBookks,new BookComaparator);
    
  4. # 4 楼答案

    当您执行此语句时:

    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());
    

    希望能有帮助

  5. # 5 楼答案

    魔术发生在这一行:

    sortedBooks = booksArray;
    

    您没有制作booksArray的副本。实际情况是,您正在使sortedBooks引用booksArray所引用的数组

    这意味着不会创建新数组。你只有两个名字是指同一件事。这就是为什么在对sortedBooks进行更改后,更改也会发生在booksArray

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

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

    或者使用copyOf方法:

    sortedBooks = Arrays.copyOf(booksArray, booksArray.length);
    
  6. # 6 楼答案

    sortedBooks is now a duplicate of booksArray, yes?

    实际上没有。因为您刚刚将sortedBooks引用重新分配给了booksArray具有引用的相同数组对象。 因此,对一个数组对象有两个引用。第二个符合垃圾收集的条件