【问题标题】:Java - remove last known item from ArrayListJava - 从 ArrayList 中删除最后一个已知项目
【发布时间】:2011-03-31 17:43:57
【问题描述】:

好的,这是我的ArrayList

private List<ClientThread> clients = new ArrayList<ClientThread>();

这就是我想要做的:
我正在尝试从上面发布的ArrayList 中删除最后一个已知项目。我正在尝试使用以下代码执行此操作:

    } catch(SocketException re) {


                            String hey = clients.get(clients.size());
                            ClientThread.remove(hey);
                            System.out.println(hey + " has logged out.");
                            System.out.println("CONNECTED PLAYERS: " + clients.size());
}

但我收到此错误:

C:\wamp\www\mystikrpg\Server.java:147: incompatible types
found   : Server.ClientThread
required: java.lang.String
                        String hey = clients.get(clients.size());
                                                ^
C:\wamp\www\mystikrpg\Server.java:148: cannot find symbol
symbol  : method remove(java.lang.String)
location: class Server.ClientThread
                        ClientThread.remove(hey);
                                    ^
2 errors

我做错了什么? 它应该从我的ArrayList 中删除最后一个已知项目。

【问题讨论】:

    标签: java arraylist


    【解决方案1】:

    应该是:

    ClientThread hey = clients.get(clients.size() - 1);
    clients.remove(hey);
    

    或者你可以这样做

    clients.remove(clients.size() - 1);
    

    减号是因为size()返回的是元素个数,但是ArrayList的第一个元素的索引是0而不是1。

    【讨论】:

    • 请注意,在覆盖 .equals() 时,您可能希望使用后一个版本以确保它确实是最后一个被删除的对象。
    • 我相信如果列表中有重复项,您的第一个解决方案将无法正常工作。但是,在某些情况下,您可能需要此类功能。
    • 需要注意的是,从数组列表中移除一个对象是O(n)。第二种方法是恒定时间。
    • 这里解释上面的区别xenovation.com/blog/development/java/…
    【解决方案2】:

    编译器抱怨您正在尝试将ClientThread 对象列表转换为String。将hey 的类型更改为ClientThread 或将clients 的类型更改为List&lt;String&gt;

    另外:列表的有效索引是从 0 到 size()-1。

    所以你可能想写

       String hey = clients.get(clients.size()-1);
    

    【讨论】:

    • +1 表示传递给 get() 的索引是错误的,我没听懂。
    【解决方案3】:

    这一行意味着您实例化了一个“ClientThread 对象列表”。

    private List<ClientThread> clients = new ArrayList<ClientThread>();
    

    这条线有两个问题。

    String hey = clients.get(clients.size());
    

    1.这部分行:

    clients.get(clients.size());
    

    ALWAYS 抛出 IndexOutOfBoundsException,因为集合大小总是比其最后一个元素的索引大一;

    2. 编译器抱怨类型不兼容,因为您不能将 ClientThread 对象分配给 String 对象。正确的应该是这样的。

    ClientThread hey = clients.get(clients.size()-1);
    

    最后但并非最不重要。如果您知道要删除的对象的索引,只需编写

     clients.remove(23); //Lets say it is in 23. index
    

    不要写

       ClientThread hey = clients.get(23); 
    
       clients.remove(hey);
    

    因为您强制列表搜索您已经知道的索引。 如果您打算稍后对已删除的对象执行某些操作。写

       ClientThread hey = clients.remove(23); 
    

    这样您可以删除对象并在同一行获取对它的引用。

    奖励:永远不要用名称“hey”调用您的实例变量。找到有意义的东西。

    这是您已更正且可立即运行的代码:

    public class ListExampleForDan {
    
        private List<ClientThread> clients = new ArrayList<ClientThread>();
    
        public static void main(String args[]) {
    
            clients.add(new ClientThread("First and Last Client Thread"));
    
            boolean success = removeLastElement(clients);
    
            if (success) {
    
                System.out.println("Last Element Removed.");
    
            } else {
    
                System.out.println("List Is Null/Empty, Operation Failed.");
    
            }
    
        }
    
        public static boolean removeLastElement(List clients) {
    
            if (clients == null || clients.isEmpty()) {
    
                return false;
    
            } else {
    
                clients.remove(clients.size() - 1);
    
                return true;
    
            }
    
        }
    }
    

    享受吧!

    【讨论】:

      【解决方案4】:

      您试图将clients.get(clients.size()) 的返回值分配给字符串hey,但返回的对象是ClientThread,而不是字符串。作为Andre mentioned,你也需要使用正确的索引。

      就您的第二个错误而言,ClientThread 类型上没有静态方法 remove()。确实,您可能想要 List 实例 clients 的 remove 方法。

      您可以从列表中删除最后一项(如果有的话),如下所示。由于 remove 也会返回被移除的对象,因此您可以捕获返回并使用它打印出名称:

      int size = clients.size();
      
      if (size > 0) {
          ClientThread client = clients.remove(size - 1);
      
          System.out.println(client + " has logged out.");
          System.out.println("CONNECTED PLAYERS: " + clients.size());
      }
      

      【讨论】:

      • +1 用于在正确的对象上使用 .remove()。使用 remove() 的返回值的虚构额外 +1。
      【解决方案5】:

      同样,我认为您应该致电 clients 列表中的 remove

      ClientThread hey = clients.get(clients.size()-1);
      clients.remove(hey);
      System.out.println(hey + " has logged out.");
      System.out.println("CONNECTED PLAYERS: " + clients.size());
      

      不过,在这种情况下,我会使用 LinkedList 的堆栈函数。

      ClientThread hey = clients.removeLast()
      

      【讨论】:

        【解决方案6】:

        第一个错误:由于某种原因,您将 ClientThread 转换为 String

        第二个错误:您没有在您的List 上调用remove

        是作业吗?如果是这样,您可能需要使用该标签。

        【讨论】:

          【解决方案7】:

          你需要了解java generics。你有一个ClientThread 的列表,但试图获取String。您还有其他错误,但这是一个非常基本的错误。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-06-03
            • 2013-08-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-05-29
            • 2022-08-05
            相关资源
            最近更新 更多