将内部类对象添加到ArrayList的问题

时间:2015-05-02 19:50:25

标签: java sockets arraylist

我有一个客户端,它将一个扩展Ellipse2D.Double的TestEllipse发送到服务器。服务器将椭圆包装在ArrayList中,调用其updatePosition方法,该方法将椭圆的x坐标加10,然后将列表发送回客户端。

当椭圆的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标记为易变,但它没有帮助。

我还尝试创建一个返回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() + " ");
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您有两个独立的进程在运行。每个线程都在其自己的进程中。它们不共享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();
    }
}