首页 > 解决方案 > 使用 java final 关键字时出错,无法修改 final ArrayList 的副本

问题描述

我收到无法修改只读列表的错误。但是我只修改了 B (这是只读列表的副本)- 那为什么它不起作用呢?

给定一个包含 m * n 个元素(m 行,n 列)的矩阵,以螺旋顺序返回矩阵的所有元素。

错误:

Exception in thread "main" java.lang.UnsupportedOperationException: Read
only list. Mutations not allowed!
at MyList.remove(Main.java:43)
at Solution.goLeft(Solution.java:55)
at Solution.spiralOrder(Solution.java:13)
at Main.main(Main.java:329)

JAVA代码:

public class Solution {
// DO NOT MODIFY THE LIST. IT IS READ ONLY
    ArrayList<Integer> spiralOrderList;
public ArrayList<Integer> spiralOrder(final List<ArrayList<Integer>> A) {
    spiralOrderList = new ArrayList<Integer>();
    List<ArrayList<Integer>> B = A;
    int currentRow=0;
    while(A.size()!=0){
        B=goRight(currentRow,B);
        currentRow++;
        B=goDown(currentRow,B);
        currentRow=B.size()-1;
        B=goLeft(currentRow,B);
        currentRow=B.size()-1;
        B=goUp(currentRow,B);    
        currentRow=0;
    }
    return spiralOrderList;
}
private  List<ArrayList<Integer>> goUp(int currentRow,List<ArrayList<Integer>> A){
    while(currentRow>=0){
        System.out.println(currentRow);
        spiralOrderList.add(A.get(currentRow).get(0));//print element at start
        A.get(currentRow).remove(0);//remove element
        currentRow--;
    }
    return A;
}
private List<ArrayList<Integer>> goDown(int currentRow,List<ArrayList<Integer>> A){
    while(currentRow<A.size()){
        int size = A.get(currentRow).size();//get Last Element Index 
        spiralOrderList.add(A.get(currentRow).get(size-1));
        System.out.println(A.get(currentRow).get(size-1));
        A.get(currentRow).remove(A.get(currentRow).get(size-1));//remove element
        currentRow++;
    }
    return A;
}
private List<ArrayList<Integer>> goRight(int currentRow,List<ArrayList<Integer>> A){
    for(int i=0;i<A.get(currentRow).size();i++)
    {
        System.out.println(A.get(currentRow).get(i));
        spiralOrderList.add(A.get(currentRow).get(i));
    }
    A.get(currentRow).clear();//remove row
    return A;
}
private List<ArrayList<Integer>> goLeft(int currentRow,List<ArrayList<Integer>> A){
    for(int i=A.get(currentRow).size()-1;i>=0;i--)
    {
        System.out.println(A.get(currentRow).get(i));
        spiralOrderList.add(A.get(currentRow).get(i));
    }
    System.out.println((A.size()-1)+"--");
    A.remove(A.get(currentRow));//remove row
    System.out.println((A.size()-1)+"//");
    return A;
}
}

链接 - https://www.interviewbit.com/problems/spiral-order-matrix-i/

 Sample input 3 3 1 2 3 4 5 6 7 8 9 in interview bit

标签: javalistarraylistintegerfinal

解决方案


ArrayList is an Object. And in Java, when you use the assignment operator with objects it will not make a fresh copy but instead it will make both reference variables point to the same Object.
In your case

List<ArrayList<Integer>> B = A;

B is pointing to same final ArrayList as A.

If you want a copy of A then use.

List<ArrayList<Integer>> B = new ArrayList<>(A);   //pass List A as argument of constructor 

推荐阅读