如何将客户存储在列表中
How to store Clients in a list
我正在 运行 连接服务器,我有一个客户端类型的数组列表
当客户端连接通过
ServerSocket.accept()
我将新的 Socket 传递给 arraylists 构造函数。这是构造函数中的所有内容
this.add(new Client(Socket client));
我的问题是,当客户端断开连接时,它会关闭套接字,但不会删除它在数组列表中的位置,并将所有内容都向下移动一位。所以数组列表不断变大。
我可以do/use解决这个问题吗?
有时我会 运行 命令将在所有客户端上执行,这就是我将客户端存储在数组列表中的原因。
是否有更好的替代方法将客户端存储在服务器中?
更新 1
类 处于起步阶段。实施的很少。到目前为止,答案中建议的 HashMap 选项最适合我。感谢您的回复
有趣的问题。
你应该在这里使用散列映射.. 添加以对象为值的客户端并使用一些键。每当您断开连接时,将其从地图上移除。
一个很好的问题,我应该是什么关键?可能是对象引用(取决于您的选择)或任何相对于客户端对象而言唯一的东西(必须有一些东西,如果没有,您可以轻松生成它)。
Map<Integer,Client> clientMap = new HashMap<Integer,Client>();
您应该从 ArrayList 中删除 Client,列表中的其余元素将自动沿着列表向上移动。
//java.util.ArrayList.remove(Object) shifts any subsequent elements
// to the left (subtracts one from their indices).
比如说,如果Client是Client A,ArrayList是ArrayListA,那么你应该申请
ArrayListA.remove(ClientA);
但是,更好的方法将使用 HashMap 来存储客户端信息,如 Danyal Sandeelo 的回答中所述。
如果客户端是你自己的class,那你可以试试这个:
public class Client {
public final List<Client> clients;
public Client(List<Client> clients, Socket socketClient) {
this.clients = clients;
clients.add(this);
}
public void disconnect() {
clients.remove(this);
}}
List<Client> clients = new ArrayList<Client>();
new Client(clients, new Socket());
new Client(clients, new Socket());
new Client(clients, new Socket());
做了很多假设,例如,我假设您的 Client
class 中有一个 disconnect()
方法。如果您想要更准确的解决方案,请提供更多详细信息。
一种方法是将回调传递给您的客户端,以便它在完成后从 ArrayList
中删除自己。非常粗糙的实现:
public class Callback {
private ArrayList<Client> clients;
public Callback(ArrayList<Client> clients) {
this.clients = clients;
}
public void remove(Client client) {
clients.remove(client);
}
}
然后在实例化Client
时传递Callback
:
Callback callback = new Callback(list);
list.add(new Client(socket, callback));
然后调用回调的remove()
方法。如果 Client
有一个 disconnect()
方法,那么在里面你可以做
public void disconnect() {
// bla bla
callback.remove(this);
}
这样 Client
可以在需要时自行清理 :)
我正在 运行 连接服务器,我有一个客户端类型的数组列表 当客户端连接通过 ServerSocket.accept() 我将新的 Socket 传递给 arraylists 构造函数。这是构造函数中的所有内容
this.add(new Client(Socket client));
我的问题是,当客户端断开连接时,它会关闭套接字,但不会删除它在数组列表中的位置,并将所有内容都向下移动一位。所以数组列表不断变大。
我可以do/use解决这个问题吗?
有时我会 运行 命令将在所有客户端上执行,这就是我将客户端存储在数组列表中的原因。
是否有更好的替代方法将客户端存储在服务器中?
更新 1
类 处于起步阶段。实施的很少。到目前为止,答案中建议的 HashMap 选项最适合我。感谢您的回复
有趣的问题。
你应该在这里使用散列映射.. 添加以对象为值的客户端并使用一些键。每当您断开连接时,将其从地图上移除。
一个很好的问题,我应该是什么关键?可能是对象引用(取决于您的选择)或任何相对于客户端对象而言唯一的东西(必须有一些东西,如果没有,您可以轻松生成它)。
Map<Integer,Client> clientMap = new HashMap<Integer,Client>();
您应该从 ArrayList 中删除 Client,列表中的其余元素将自动沿着列表向上移动。
//java.util.ArrayList.remove(Object) shifts any subsequent elements
// to the left (subtracts one from their indices).
比如说,如果Client是Client A,ArrayList是ArrayListA,那么你应该申请
ArrayListA.remove(ClientA);
但是,更好的方法将使用 HashMap 来存储客户端信息,如 Danyal Sandeelo 的回答中所述。
如果客户端是你自己的class,那你可以试试这个:
public class Client {
public final List<Client> clients;
public Client(List<Client> clients, Socket socketClient) {
this.clients = clients;
clients.add(this);
}
public void disconnect() {
clients.remove(this);
}}
List<Client> clients = new ArrayList<Client>();
new Client(clients, new Socket());
new Client(clients, new Socket());
new Client(clients, new Socket());
做了很多假设,例如,我假设您的 Client
class 中有一个 disconnect()
方法。如果您想要更准确的解决方案,请提供更多详细信息。
一种方法是将回调传递给您的客户端,以便它在完成后从 ArrayList
中删除自己。非常粗糙的实现:
public class Callback {
private ArrayList<Client> clients;
public Callback(ArrayList<Client> clients) {
this.clients = clients;
}
public void remove(Client client) {
clients.remove(client);
}
}
然后在实例化Client
时传递Callback
:
Callback callback = new Callback(list);
list.add(new Client(socket, callback));
然后调用回调的remove()
方法。如果 Client
有一个 disconnect()
方法,那么在里面你可以做
public void disconnect() {
// bla bla
callback.remove(this);
}
这样 Client
可以在需要时自行清理 :)