Java 将内部类对象添加到ArrayList时出现问题
我有一个客户端,它向服务器发送一个TestEllipse,它扩展了Java 将内部类对象添加到ArrayList时出现问题,java,sockets,arraylist,Java,Sockets,Arraylist,我有一个客户端,它向服务器发送一个TestEllipse,它扩展了Ellipse2D.Double。服务器将椭圆包装在ArrayList中,调用其updatePosition方法,该方法将椭圆的x坐标加10,然后将列表发送回客户端 当椭圆的x坐标等于或超过100时,应将椭圆添加到removeList,它是。。。但事实并非如此。在updatePosition方法中,当我打印removeList的大小时,这是输出: 0 0 0 0 1 2 3 4 5 0 0 0 0 0 0 0 0 0 因此椭圆
Ellipse2D.Double
。服务器将椭圆包装在ArrayList中,调用其updatePosition
方法,该方法将椭圆的x坐标加10,然后将列表发送回客户端
当椭圆的x坐标等于或超过100时,应将椭圆添加到removeList
,它是。。。但事实并非如此。在updatePosition
方法中,当我打印removeList
的大小时,这是输出:
0 0 0 0 1 2 3 4 5
0 0 0 0 0 0 0 0 0
因此椭圆确实被添加到了列表中(尽管多次,这是不相关的)。但是在main
方法中,似乎根本没有添加椭圆,因为打印removeList
的大小会产生以下输出:
0 0 0 0 1 2 3 4 5
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.*;
导入java.net。*;
导入java.util.*;
公共类测试服务器{
公共静态void main(字符串[]args){
试一试{
列表=新的ArrayList();
ServerSocket侦听器=新的ServerSocket(31362);
Socket=listener.accept();
ObjectOutputStream oos=新的ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois=新的ObjectInputStream(socket.getInputStream());
while(true){
试一试{
TestClient.TestEllipse addEllipse=(TestClient.TestEllipse)ois.readObject();
if(addEllipse!=null)
列表。添加(附录);
TestClient.TestEllipse removeEllipse=(TestClient.TestEllipse)ois.readObject();
如果(removeEllipse!=null)
列表。删除(removeEllipse);
for(TestClient.TestEllipse椭圆:列表)
椭圆。updatePosition();
oos.writeObject(列表);
oos.reset();
}捕获(ClassNotFoundException ex){
例如printStackTrace();
}
}
}捕获(IOEX异常){
例如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() + " ");
}
}
}
import java.io.*;
导入java.net.Socket;
导入java.util.*;
公共类TestClient实现了可序列化{
静态volatile List removeList=new ArrayList();
公共静态void main(字符串[]args){
试一试{
列表=新的ArrayList();
TestEllipse t=newtestclient()。newtestellipse(50250);
套接字=新套接字(“localhost”,31362);
ObjectOutputStream oos=新的ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois=新的ObjectInputStream(socket.getInputStream());
while(true){
试一试{
oos.writeObject(t);
t=零;
//System.out.print(removeList.size()+);
如果(removeList.size()>0)
oos.writeObject(removeList.remove(0));
其他的
oos.writeObject(空);
list=(list)ois.readObject();
睡眠(500);
}catch(ClassNotFoundException | InterruptedException ex){
例如printStackTrace();
}
}
}捕获(IOEX异常){
例如printStackTrace();
}
}
公共类TestEllipse扩展了java.awt.geom.Ellipse2D.Double实现了可序列化{
int x,y;
公共测试工具(整数x,整数y){
super(x,y,10,10);
这个.x=x;
这个。y=y;
}
public void updatePosition(){
如果((x+=10)>=100)
删除列表。添加(此);
//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();
}
}
for(ListIterator li=list.ListIterator();li.hasNext();)
{
TestEllipse elipse=(TestEllipse)li.next();
if(elipse.isForRemove())
{
li.remove();
}
}