-4

I'm trying to assign a global variable's data and alter the local variable's data, but then when I change the local variable's structure, the global variable gets changed as well.

private void remove(Message M) {
      int           p = list.lastIndexOf(M);
      List<Message> x = list;
      list.remove(p);
      indexedMessages.remove(M.getMessageid());
      notifyItemRemoved(p);
      notifyItemRangeChanged(p, list.size());

// Removing the following items from "x" also causes the elements to be removed from recycleView.
      x.remove(0);
      x.remove(x.size() - 1);
}

Two things I don't understand :

  1. Why is "x" affecting "list"
  2. And why is "notifyItemRemoved" triggered again.

Anyway, on the original "list" (private List list), the first & last items are just placeholders. When an item is removed from this list, I want to store a new copy of that list without the placeholder.

The placeholders get added every time the adapter is created.

Relm
  • 7,923
  • 18
  • 66
  • 113

1 Answers1

3

Before local variable x is made,

After local variable x is made,

After you removed an element from x,

Because the variable x is a pointer/reference to an object of type List<Message> called list. Therefore, changes to x will simultaneously be applied to list since they both point to the same object.

If you want to make changes to x without affecting the global variable, then you have to make x pointing to a new object and copy all the contents of the global variable into x. Note that this can be redundant. For example, this will work,

List<Message> x = new ArrayList<Message>();
//modify x here

For reasons pointed out in the comments, this is redundant because

  • Local variables are lost after the method is finished
  • List<Message> x = ArrayList<Message>() can be rewritten as List<Message> x = ArrayList<>() since the object type can be inferred from List<Message> so there's no need to restate it

Also if we have :

List<String> a = new ArrayList<String>();
a.add("a");
a.add("b");
a.add("c");

We can copy "a"'s contents into "b" as follows.

List<String> b = new ArrayList<>(a);
Relm
  • 7,923
  • 18
  • 66
  • 113
Chris Gong
  • 8,031
  • 4
  • 30
  • 51
  • `List x = new List()` is abstract and can't be instantiated there, & then earlier I tried `List x = new ArrayList()`, which just becomes redundant. – Relm Oct 08 '16 at 10:36
  • @Relm have you tried `Listx = new ArrayList()`? – Chris Gong Oct 08 '16 at 10:38
  • Yes, just had a typo in my previous comment, `new ArrayList()` becomes redundant. – Relm Oct 08 '16 at 10:41
  • @Relm Are you saying it's redundant in terms of space is being wasted to create a new list? Otherwise, may I ask why you need to make changes to local variable x without changing the global variable if you're not willing to create a new list? – Chris Gong Oct 08 '16 at 10:42
  • No, I'm willing to create a new List, that's what I'm trying to do, but `new ArrayList()` is not being assigned, it's even greyed out in Android Studio with a "redundant" warning. – Relm Oct 08 '16 at 10:45
  • @Relm Well in this case it is redundant since you don't return `x`. So whatever changes you make to `x` along with the list `x` will be lost once the method is finished. But for the most part, that warning can be ignored. I've gotten it before and you can read more about it here, http://stackoverflow.com/questions/23159351/android-studio-says-local-variable-is-redundant – Chris Gong Oct 08 '16 at 10:49
  • Also redundant is that `new ArrayList()` can be re-written as `new ArrayList<>()` because the generic type argument can be inferred due to the declared `List` type. Still, +1 for the giant drawings to explain the most elementary concepts. – code_dredd Oct 08 '16 at 10:49
  • Still, you need to fix the example or just remove it. I think your explanation prior to the examples was enough. – code_dredd Oct 08 '16 at 10:51
  • @ray Thank you for the suggestion, just edited my answer! – Chris Gong Oct 08 '16 at 10:55
  • I think I should accept your answer, but then for some reasons I still don't understand, this : `List x = new ArrayList<>(list);` is what works. Can you please put that in your answer. – Relm Oct 08 '16 at 11:05
  • 1
    @Relm understandable, I decided to compromise and include both lines of reasoning in my answer. Good luck coding! – Chris Gong Oct 08 '16 at 11:10