[英]Issue With Adding Inner Class Object to ArrayList
我有一個客戶端,該客戶端發送一個TestEllipse並將其擴展到服務器Ellipse2D.Double
。 服務器將橢圓包裝在ArrayList中,調用其updatePosition
方法,該方法將10添加到橢圓的x坐標中,並將列表發送回客戶端。
當橢圓的x坐標等於或超過100時,應將橢圓添加到removeList
,它是...但不是。 在updatePosition
方法中,當我打印removeList
的大小時,將輸出:
0 0 0 0 1 2 3 4 5
因此,確實將橢圓添加到了列表中(盡管多次,這是無關緊要的)。 但是在main
方法中,好像根本沒有添加橢圓,因為打印removeList
的大小會產生以下輸出:
0 0 0 0 0 0 0 0 0
我以為更改沒有在線程中反映出來,所以我嘗試將removeList
標記為volatile,但這沒有幫助。
我還嘗試創建一個返回removeList
的訪問器方法,但這也不起作用。
如何將橢圓添加到removeList
以便可以從main
方法訪問它?
在服務器端:
import java.io.*;
import java.net.*;
import java.util.*;
public class TestServer {
public static void main(String[] args) {
try {
List<TestClient.TestEllipse> list = new ArrayList<TestClient.TestEllipse>();
ServerSocket listener = new ServerSocket(31362);
Socket socket = listener.accept();
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
while (true) {
try {
TestClient.TestEllipse addEllipse = (TestClient.TestEllipse) ois.readObject();
if (addEllipse != null)
list.add(addEllipse);
TestClient.TestEllipse removeEllipse = (TestClient.TestEllipse) ois.readObject();
if (removeEllipse != null)
list.remove(removeEllipse);
for (TestClient.TestEllipse ellipse : list)
ellipse.updatePosition();
oos.writeObject(list);
oos.reset();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
在客戶端:
import java.io.*;
import java.net.Socket;
import java.util.*;
public class TestClient implements Serializable {
static volatile List<TestEllipse> removeList = new ArrayList<TestEllipse>();
public static void main(String[] args) {
try {
List<TestEllipse> list = new ArrayList<TestEllipse>();
TestEllipse t = new TestClient().new TestEllipse(50, 250);
Socket socket = new Socket("localhost", 31362);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
while (true) {
try {
oos.writeObject(t);
t = null;
// System.out.print(removeList.size() + " ");
if (removeList.size() > 0)
oos.writeObject(removeList.remove(0));
else
oos.writeObject(null);
list = (List<TestEllipse>) ois.readObject();
Thread.sleep(500);
} catch (ClassNotFoundException | InterruptedException ex) {
ex.printStackTrace();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
public class TestEllipse extends java.awt.geom.Ellipse2D.Double implements Serializable {
int x, y;
public TestEllipse(int x, int y) {
super(x,y,10,10);
this.x = x;
this.y = y;
}
public void updatePosition() {
if ((x += 10) >= 100)
removeList.add(this);
//System.out.print(removeList.size() + " ");
}
}
}
您有兩個單獨的進程正在運行。 每個線程都在其自己的進程中。 它們不共享TestClient中定義的removeList對象。 在TestServer中,當您調用ellipse.updatePosition()時,它將在列表中的橢圓上執行。 該列表已在TestServer#main方法的范圍內重新創建,並且與TestClient#main中定義的removeList沒有任何關系。
可以修改TestEllipse本身以使其具有有關刪除的狀態:
public static class TestEllipse
extends java.awt.geom.Ellipse2D.Double
implements Serializable
{
int x, y;
boolean forRemove;
public void setForRemove(boolean forRemove)
{
this.forRemove = forRemove;
}
public boolean isForRemove()
{
return forRemove;
}
public TestEllipse(int x, int y)
{
super(x,y,10,10);
this.x = x;
this.y = y;
}
public void updatePosition()
{
if ((x += 10) >= 100)
{
setForRemove(true);
}
}
public String toString()
{
return String.format("{x:%d,y:%d,forRemove:%b}",x,y,isForRemove());
}
}
然后,當您有一個列表時,刪除標記為要刪除的橢圓:
for (ListIterator<TestEllipse> li = list.listIterator() ; li.hasNext();)
{
TestEllipse elipse = (TestEllipse)li.next();
if (elipse.isForRemove())
{
li.remove();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.