簡體   English   中英

向ArrayList添加內部類對象的問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM