Java 如何使用AbstractList

Java 如何使用AbstractList,java,data-structures,Java,Data Structures,我刚开始使用Java不久。我试图使聊天信使(客户端服务器),我需要一个数据结构,我可以存储在线用户(一个套接字和一个字符串包含用户名)。现在我做了很多研究,认为AbstractList可以帮助我,但我很快就遇到了一个问题 public class Collections <E> extends AbstractList<E> { private int size; private E[] list; public Collections() {

我刚开始使用Java不久。我试图使聊天信使(客户端服务器),我需要一个数据结构,我可以存储在线用户(一个套接字和一个字符串包含用户名)。现在我做了很多研究,认为AbstractList可以帮助我,但我很快就遇到了一个问题

public class Collections <E> extends AbstractList<E> {

    private int size;
    private E[] list;

    public Collections() {
        size = 0;
        list = new E[50];
    }

    @Override
    public E get(int index) {
        return list[index];
    }
    @Override
    public boolean add(E element) {


        return false;
    }

    @Override
    public int size() {
        return list.length;
    }
    public static void main(String[] args) {
        Collections <String>obj = new Collections();
        obj.add(new String("1"));
        obj.add(new String("5"));

        System.out.println("Size = " + obj.size());
    }
}
但这会导致一般的初始化错误。简而言之,我不知道如何初始化list对象。 现在我有三个问题:

  • 我创建服务器上所有客户机列表的方法好吗
  • 我应该如何处理add()函数
  • 为什么第一行有两个“?很明显,它是一个模板,但您不需要它只使用一次吗?很明显,两个地方都需要它,那么第一个是用来做什么的,第二个是用来做什么的?(我从中学到的教程没有安静地解释)

  • 您的代码存在一些设计问题,我认为这些问题源于您是初学者的事实:

    • 除非您确实需要某种特殊类型的列表,否则无需扩展
      AbstractList
      。您可以简单地使用
      List
      的具体实现,如
      LinkedList
      ArrayList
    • 您的代码存在设计问题。您的服务器不是列表。但这是您的代码所说的,因为您的主类正在扩展
      AbstractList
      。相反,您的服务器应该使用列表。因此,正确的方法是使用一个内部
      列表
      实例来跟踪您的客户机

    您的方法从根本上是错误的,所以我建议您阅读一些关于Java和面向对象编程的入门文章。从您的代码来看,似乎您对OOP实际上是什么有一些误解。

    要将项目添加到列表中,您可以这样做,您不需要创建自己的列表类

    List<String> myList = new ArrayList<String>();
    myList.add("Peter");
    myList.add("Susan");
    
    或者您可以创建自己的用户名和套接字类

    public class UsernameSocketPair{
      private String name;
      private Socket socket;
      public UsernameSocketPair(String name, Socket socket){
         this.name = name;
         this.socket = socket;
      }
    
      public String getName(){
         return name;
      }
    
      public Socket socket(){
         return socket;
      }
    }
    
    然后可以将其放入如下列表中

    List<UsernameSocketPair> myList = new ArrayList<UsernameSocketPair>();
    myList.add(new UsernameSocketPair("Peter", petersSocket));
    
    List myList=new ArrayList();
    add(新的UsernameSocketPair(“Peter”,petersocket));
    
    这是否是一个好主意,取决于代码的其余部分及其结构

    要明确回答这些问题:

  • 这取决于代码的其余部分及其结构
  • 首先,不要使用E[]使用Object[]并在“获取”元素时强制转换为E。这样您就可以实例化(例如Object[]list=new Object[20]
  • E在类声明中出现了两次,因为您正在扩展AbstractList类型的类,并且您正在用E参数化您的类。例如,您可以这样做
  • 以下是:

    public class MyList extends AbstractList<String>{
    
    } 
    
    公共类MyList扩展了AbstractList{
    } 
    
    下面是一个非常简单的示例,说明了如何根据需要实现抽象列表参数化的具体版本

    public class MyList <E> extends AbstractList<E> {
    
        private Object[] list = new Object[10];
        private int size = 0;
    
    
        public E get(int i){
            if(i >= size) throw new IndexOutOfBoundsException("duh!");
            return (E)list[i];
        }
    
        public boolean add(E e){
            if(size >= list.length){
                Object[] newList = new Object[list.length + 10];
                System.arraycopy(list,0, newList, 0, list.length);
                list = newList;
            }
            list[size] = e;
            size++;
            return true;
        }
    
        public int size(){
            return size;
        }
    
        public static void main(String[] args){
            List<String> l = new MyList<String>();
            for(int i = 0; i < 100; i++){
                l.add(""+i);
            }
            System.out.println(l.size());
        }
    
    }
    
    公共类MyList扩展了AbstractList{
    私有对象[]列表=新对象[10];
    私有整数大小=0;
    公共电子商务(int i){
    如果(i>=size)抛出新的IndexOutOfBoundsException(“duh!”);
    返回(E)列表[i];
    }
    公共布尔加法(E){
    如果(大小>=列表长度){
    Object[]newList=新对象[list.length+10];
    数组复制(list,0,newList,0,list.length);
    列表=新列表;
    }
    列表[大小]=e;
    大小++;
    返回true;
    }
    公共整数大小(){
    返回大小;
    }
    公共静态void main(字符串[]args){
    列表l=新的MyList();
    对于(int i=0;i<100;i++){
    l、 加上(“+i”);
    }
    System.out.println(l.size());
    }
    }
    
    您不能直接创建泛型数组。请改用
    ArrayList
    。您应该从初学者阅读java编程开始。您不仅不理解java语法,而且从上面的代码中,您甚至不知道面向对象编程背后的思想。在开始之前,请先阅读一下。@5gon12eder你能演示如何使用ARRAYLIST的示例代码吗?我建议你开始。也可以看到@的答案。@ 5Go12EDER。谢谢。我会读它。这不是我的服务器类。我只使用java来理解集合类的概念,但我需要它提供数据结构。我最初考虑过ARARYLIST,但不认为是BE。tter选项因此转到AbstractList。正如我提到的,我需要它来保存所有在线客户端(套接字和用户名)的列表。你能解释一下ArrayList有什么问题吗?@Vivin现在我已经阅读了5gon12eder的链接,我更了解ArrayList的工作原理,并意识到使用它没有什么问题。事实上我刚刚实现了它。谢谢!非常感谢这正是我需要的,但如果我可能会问为什么我更喜欢Maps而不是ArrayList或AbstractList?苏因此,如果您不知道列表中的索引是什么,您可以通过值(在本例中是“Peter”而不是1)来检索。否则,您将不得不扫描整个列表。Hmmm。收到了,非常感谢!但要明确的是,它实际上是一个哈希表,而且由于userid是唯一的,我们可以获取提供用户名的值,但问题是,您如何或何时在这里告诉字符串是键?以及如何以数字的形式表示字符串?根据我的发现erstand HashKey适用于数字而不是字符串。如果我在工作,请纠正我。map和table之间的区别在于table是线程安全的,因此速度较慢。这就是comp sci中java的区别。我认为table、map和dictionary都是可互换的。key是put方法中的第一个参数。java使用hashcode方法作为HashMap中的键,在大多数情况下,如果在HashMap(或表)键中使用自定义类,则需要重写它。
    List<UsernameSocketPair> myList = new ArrayList<UsernameSocketPair>();
    myList.add(new UsernameSocketPair("Peter", petersSocket));
    
    public class MyList extends AbstractList<String>{
    
    } 
    
    public class MyList <E> extends AbstractList<E> {
    
        private Object[] list = new Object[10];
        private int size = 0;
    
    
        public E get(int i){
            if(i >= size) throw new IndexOutOfBoundsException("duh!");
            return (E)list[i];
        }
    
        public boolean add(E e){
            if(size >= list.length){
                Object[] newList = new Object[list.length + 10];
                System.arraycopy(list,0, newList, 0, list.length);
                list = newList;
            }
            list[size] = e;
            size++;
            return true;
        }
    
        public int size(){
            return size;
        }
    
        public static void main(String[] args){
            List<String> l = new MyList<String>();
            for(int i = 0; i < 100; i++){
                l.add(""+i);
            }
            System.out.println(l.size());
        }
    
    }