x = y是否使x指针指向y?

时间:2016-06-04 15:52:22

标签: java android variables

我很抱歉这么愚蠢的问题,但我无法更好地描述我的问题。我有2个班级:

    //First Class
    public class VKtracks extends Fragment {

        RecyclerView list;
        SongListAdapter listAdapter;
        private ArrayList<song> songs = new ArrayList<>();
        MainActivity mainActivity;

        public VKtracks(){

        }

        @Override
        public void onActivityCreated (Bundle savedInstanceState){
            super.onActivityCreated(savedInstanceState);
            mainActivity = (MainActivity)getActivity();
            songs = mainActivity.songs;
            Iterator<song> itr = songs.iterator();
            while (itr.hasNext()) {
                song element = itr.next();
                if(element.getSource() == 0){
                    itr.remove();
                }
            }
        }

    //Second class

public class Tracks extends Fragment {


    RecyclerView list;
    private MediaPlayer mp = new MediaPlayer();
    SongListAdapter listAdapter;
    private ArrayList<song> songs = new ArrayList<>();
    ImageButton playButton;
    boolean playerActive = false;
    MainActivity mainActivity;
    int mLastFirstVisibleItem = 0;


    public Tracks() {
    }

    @Override
    public void onActivityCreated (Bundle savedInstanceState){
        super.onActivityCreated(savedInstanceState);
        mainActivity = (MainActivity)getActivity();
        songs = mainActivity.songs;
        listAdapter = new SongListAdapter(getContext(),songs, mainActivity);
        listAdapter.notifyDataSetChanged();
        list.setHasFixedSize(true);
        LinearLayoutManager llm = new LinearLayoutManager(getActivity());
        list.setLayoutManager(llm);
        list.setAdapter(listAdapter);
    }
}

在这两节课中,我都会收到MainActivity的歌曲列表。在Tracks类中,我只是用它填充RecyclerView,而在VKtracks中,我使用迭代器删除不必要的项目并填充另一个RecyclerView。最后,我有2个类似的过滤列表。如果我在VKTracks类中评论过滤部分,我会得到2个类似的未列表。

那么,为什么会这样呢?

我能想到的唯一原因是两首歌ArrayLists都是MainActivity中歌曲ArrayList的诗人。

5 个答案:

答案 0 :(得分:3)

你的推理是正确的。指针Tracks.songsVKTracks.songsMainActivity.songs都指向同一个列表,因此修改任何一个都会更改所有三个。尝试使用ArrayListTracks中的VXTracks复制构造函数创建三个唯一的数组列表。为此,请更换线



songs = mainActivity.songs;

songs = new ArrayList(mainActivity.songs);Tracks中的VKTracks

。{ / p>

答案 1 :(得分:0)

看起来你有两个Fragment的子类并使用它的&#34; getActivity()&#34;使用&#34; savedInstance&#34;初始化后的方法。

我的猜测是,在这两种情况下,&#34;歌曲&#34;属性为你提供了相同的指针。因此,如果您在一个地方修改列表,则会在任何地方修改它。

要停止此行为,请尝试在修改前复制此列表。

答案 2 :(得分:0)

你是对的, from cStringIO import StringIO from thread import start_new_thread as thread from time import time, sleep import wx import os class Player (wx.Frame): frames = [] curframe = 0 fetched = 0.0 imgduration = 1/24.0 path = "Mov" opened = 1 canclose = 0 blockerase = 0 def __init__ (self): wx.Frame.__init__(self, None, -1, "Player", size=wx.GetDisplaySize(), style=wx.NO_FULL_REPAINT_ON_RESIZE | wx.CLIP_CHILDREN ) thread(self._fetcher,()) thread(self._play,()) self.Bind(wx.EVT_CLOSE, self.OnClose) self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground) self.SetBackgroundColour(wx.Colour(0, 0, 0)) fsstyle = (wx.FULLSCREEN_NOTOOLBAR | wx.FULLSCREEN_NOSTATUSBAR | wx.FULLSCREEN_NOBORDER | wx.FULLSCREEN_NOCAPTION) self.ShowFullScreen(True, fsstyle) self.Raise() def OnEraseBackground (self, e): if self.blockerase: return e.Skip() def OnClose (self, e): self.opened = 0 while self.canclose<0: sleep(0.02) e.Skip() def _draw (self): dc = wx.BufferedDC(wx.ClientDC(self)) dc.BeginDrawing() dc.Clear() f = self.frames[self.curframe] dc.DrawBitmap(f, 0, 0) dc.EndDrawing() self.curframe += 1 if self.curframe==len(self.frames): self.curframe = 0 def _play (self): self.canclose -= 1 drawdelay = 0.0 while self.opened: while self.fetched<3 and self.opened: sleep(0.1) if not self.opened: break t = time() self._draw() if not self.opened: break drawdelay = (drawdelay+(time()-t))/2.0 drawdelay = (drawdelay, self.imgduration)[drawdelay>self.imgduration] sleep(self.imgduration-drawdelay) self.canclose += 1 def _fetcher (self): self.canclose -= 1 l = os.listdir(self.path) l.sort() ll = len(l) t = time() self._fetch(l[0]) loaddelay = time()-t x = 1 print "Fetching" while self.opened: t = time() self._fetch(l[x]) x += 1 if x==ll: break loaddelay = (loaddelay+(time()-t))/2.0 #print loaddelay self.canclose += 1 print "End fetching" def _fetch (self, fname): w, h = self.GetSize() fname = os.path.join(self.path, fname) f = open(fname, "rb") data = f.read() f.close() img = wx.ImageFromStream(StringIO(data)) img.Rescale(w, h) f = wx.BitmapFromImage(img) self.frames.append(f) self.fetched += self.imgduration 将fragment.songs指向mainActivity中维护的列表。

因此,fragment.songs.remove(song)会从该列表中删除该歌曲。

此外,更改fragment.songs中的歌曲(例如添加注释)实际上会改变mainActivity.songs列表中的该对象。

要避免此行为,您必须创建列表其项目的副本。

答案 3 :(得分:0)

我不确定你在问什么,但我会尽力给你一个对象与原始值的简要解释。

考虑以下代码:

int x;
int y = 1;
x = y; //x is now 1
y = 2; //y is now 2, but x is still 1
System.out.print(y); //prints 2
System.out.print(x); //prints 1

由于int是原始值而不是对象,因此写x = y;不会使x指向y,因为y不是对象,没有什么可指的。 x只获取2的值。这与撰写x = 2;

相同

现在考虑以下代码:

Person x;
Person y = new Person("Johnny");
x = y; //x is now pointing to the same object as y
y.changeName("Felicity"); //this changes the name of the object to Felicity
y.printName(); //prints Felicity
x.printName(); //also prints Felicity

由于Person是一个对象,因此编写x = y; 使这两个变量指向同一个对象。通过任何变量对对象所做的任何更改也可以通过另一个变量显示。

答案 4 :(得分:0)

简而言之,

对于原始变量(例如int,double,char,boolean等):否

使用x = y时,

然后

x保持y的值,稍后改变y将不会影响x

中的值

对象(甚至是整数,双):是

A x;
A y = new A();// here y holds the reference of a new object of class A created.
x = y // x then holds the reference of the same object of y

所以x和y指向&#39;同一个对象(在Java的术语中称为引用)

附注:

当你说&#39;指向&#39;时,如果你在谈论c ++指针,那么原语和对象的答案都是肯定的,但是,这是一个Java问题。