2

I have one ArrayList and one TreeSet that hold the same object type.

TreeSet<StatusChangeDB> listToChange;
List<StatusChangeDB> originalList;

StatusChangeDB looks like...

public class StatusChangeDB implements Comparable<StatusChangeDB> {


    private String sector;
    private String superlayer;
    private String loclayer;
    private String locwire;
    private String problem_type;
    public StatusChangeDB() {
    }
...
...
getters and setters
hashCode()
equals(Object)
compareTo(...)
}

When original list is generated, the Object, StatusChangeDB, has 4 of 5 of its primitives set, i.e. sector, superlayer, loclayer, locwire. The originalList is displayed in a JTable which implements AbstractTableModel.

At some point in the process, the user selects the rows from the displayed table and assigns the "problemType", which creates TreeSet listToChange.

Now I would like to remove the values selected from the JTable once the "problemType" is "set". To do this, I cannot use a straight

originaList.removeAll(listToChange)

Because the objects differ by "problemType".

I have tried this method in my TableModel

public void removeRow(TreeSet<StatusChangeDB> listToChange) {
    //this.wireList.removeAll(statusChangeDBs); Does not work 
    //because objects are different
    for (StatusChangeDB row : listToChange) {
        for (StatusChangeDB statusChangeDB : originalList) {

            if (statusChangeDB.getSector().equals(row.getSector())
                    && statusChangeDB.getSuperlayer().equals(row.getSuperlayer())
                    && statusChangeDB.getLoclayer().equals(row.getLoclayer())
                    && statusChangeDB.getLocwire().equals(row.getLocwire())) {
                System.out.println("####### EQUAL #######");

                System.out.println(ro.getSector() + "  " + ro.getSuperlayer() + "  " + ro.getLoclayer() + "  "
                        + ro.getLocwire());
                 this.originalList.remove(statusChangeDB);
            }
        }
    }

This method does the job of finding the values that equal to one another, however the line

         this.originalList.remove(statusChangeDB);

produces the error

Exception in thread "AWT-EventQueue-0" java.lang.UnsupportedOperationException at java.util.AbstractList.remove(AbstractList.java:161) at java.util.AbstractList$Itr.remove(AbstractList.java:374) at java.util.AbstractCollection.remove(AbstractCollection.java:293) at database.ui.TableModel.removeRow(TableModel.java:95)

I have read the SO forums on this, but I am not able to construct the ArrayList using Arrays.asList because the ArrayList is dymnamically added to. How can I accomplish this task of removing the Object from the ArrayList? Please no comments on using DefaultTableModel instead of AbstractTable Model. The "all knowing" leaders of the project have requested the AbstractTableModel.

The code that sets the originalList is as follows:

public void setWireSet(Dataset<StatusChangeDB> wireDF) {
    setWireList(wireDF.collectAsList());
    updateTable();
}

public void setWireList(List<StatusChangeDB> wireList) {
    this.originalList = wireList;
}

Both lists are filled and when dumped to screen have the appropriate values assigned.

The assignment of originalList is if TableModel as

private List<StatusChangeDB> originalList;
private String[] colNames = { "Sector", "SuperLayer", "Layer", "Wire" };

public TableModel() {
    this.originalList = new ArrayList<StatusChangeDB>();
}
12
  • Where is the code that assigns this.originalList? Commented Jun 21, 2017 at 20:46
  • made an edit to reflect the filling of originalList. However both lists are filled appropriately. Commented Jun 21, 2017 at 20:51
  • We still can't see the type of list. It's almost certainly not java.util.ArrayList. Commented Jun 21, 2017 at 20:52
  • It is of ArrayList as stated in the question edited bottom of post to reflect how the construction of originaList is done Commented Jun 21, 2017 at 20:53
  • 1
    Obviously the implementation of the List does not support removing elements. So, you cannot use the remove. Commented Jun 21, 2017 at 20:53

3 Answers 3

4

You are getting this error because you are calling

 this.originalList.remove(statusChangeDB);

inside a for-loop which will be using the iterator of that list.

Add the values you want removed to a temporary Arraylist then remove them once the loop completes execution.

Have something like

for (StatusChangeDB row : listToChange) {

 ArrayList<StatusChangeDB> tempList = new ArrayList();
    for (StatusChangeDB statusChangeDB : originalList) {

        if (statusChangeDB.getSector().equals(row.getSector())
                && statusChangeDB.getSuperlayer().equals(row.getSuperlayer())
                && statusChangeDB.getLoclayer().equals(row.getLoclayer())
                && statusChangeDB.getLocwire().equals(row.getLocwire())) {
            System.out.println("####### EQUAL #######");

            System.out.println(ro.getSector() + "  " + ro.getSuperlayer() + "  " + ro.getLoclayer() + "  "
                    + ro.getLocwire());

  tempList.add(statusChangeDB);

        }


    }

this.originalList.removeAll(tempList);

}

Update

Keeping the above implementation

public void setWireList(List<StatusChangeDB> wireList) {
this.originalList = wireList;
}

should be

 public void setWireList(List<StatusChangeDB> wireList) {
this.originalList.addAll(wireList);
 }

Assuming

public TableModel() {
this.originalList = new ArrayList<StatusChangeDB>();

}

is called before

public void setWireList(List<StatusChangeDB> wireList) {
this.originalList = wireList;
}
Sign up to request clarification or add additional context in comments.

7 Comments

The temporary list is listToChange
this line ` this.originalList.remove(statusChangeDB);` can only work after you have exited the ` for (StatusChangeDB statusChangeDB : originalList)` loop.
I just implemented your idea that as you were updating and I still receive the same error.
Also, your code has misplacement of curly-brackets with respect to access of templist.
OK, well in my version I had templist outside both foreach loops. However, both methods, yours or mine (different in placement of templist) produce the same error that was being reported.
|
0

Firstly, you are getting UnsupportedOperationException because your List implementation doesn't support removal. To avoid this, just create an ArrayList<>:

List<StatusChangeDB> originalList = new ArrayList<>( Arrays.asList(sourceList) );

Secondly, to remove objects by some set of fields (instead of defining this logic explicitly in your removeRow method), just override equals method in StatusChangeDB which will compare those fields:

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    StatusChangeDB other = (StatusChangeDB) obj;
    return Objects.equals(sector, other.sector) && Objects.equals(superlayer, other.superlayer)
            && Objects.equals(loclayer, other.loclayer) && Objects.equals(locwire, other.locwire);
}

2 Comments

I cannot use the equals to compare because technically the are different object by the value of problemType, and I need this to be in equals for a later comparison with a MYSQL database.
Also the generation of originalList is within another Class that passes it to a service which TableModel has access to. If I try public void setWireList(List<StatusChangeDB> wireList) { this.wireList = new ArrayList<>(Arrays.asList(wireList)); // this.wireList = wireList; } i get the error Cannot infer type arguments for ArrayList<>
0

There are two types of array list. A regular one, and Arrays helper class's one, which is immodifiable.

During creation of yuor arraylist from array, instead of doing

this.originalList=Arrays.asList(pArray);

which uses the immodifiable fake ArrayList, do

this.originalList=new ArrayList(Arrays.asList(pArray));

make sure to redo imports, because you may have a namespace class for ArrayList

3 Comments

Unfortunately I need to initialize originalList in the TableModel constructor, and at time of construction the values of originalList are not known until user processed a few functions
then just use this.originalList = new ArrayList<>();
using this.originalList = new ArrayList<>(); produces same error.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.