我很抱歉这么愚蠢的问题,但我无法更好地描述我的问题。我有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的诗人。
答案 0 :(得分:3)
你的推理是正确的。指针Tracks.songs
,VKTracks.songs
和MainActivity.songs
都指向同一个列表,因此修改任何一个都会更改所有三个。尝试使用ArrayList
和Tracks
中的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问题。