如何使用AbstractList

时间:2014-10-10 18:22:07

标签: java data-structures

我刚刚开始使用Java了。我正在尝试使用聊天信使(Client-Server),我需要一个数据结构,我可以在其中存储在线用户(一个套接字和一个包含用户名的字符串)。现在我做了很多研究,并认为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 = new E[50];

但是这会产生一般的初始化错误。总之,我不知道如何初始化列表对象。 所以现在我有三个问题:

  1. 我的方法是创建服务器上所有客户端的列表吗?
  2. 我应该如何处理add()函数?
  3. 为什么第一行有两次?显然它是一个模板,但你不需要它只一次吗?显然你需要两个地方所以第一个是什么,第二个是什么? (我从中学到的教程并不安静解释)

2 个答案:

答案 0 :(得分:1)

要将项目添加到列表中,您可以执行此操作,您无需创建自己的列表类

List<String> myList = new ArrayList<String>();
myList.add("Peter");
myList.add("Susan");

现在,如果要创建所有用户名和套接字的列表,可以使用Map。像

这样的东西
Map<String, Socket> myMap = new HashMap<String, Socket>();
myMap.put("Peter", petersSocket);
myMap.put("Susan", susansSocket);

这将允许您通过用户名

检索套接字
Socket petes = myMap.get("Peter");

或者您可以创建自己的用户名和套接字类

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));

这是否是一个好主意,它取决于你的代码的其余部分以及它的结构。

明确回答问题:

  1. 这取决于你的代码的其余部分以及它的结构。
  2. 首先不要使用E []使用Object []并在你'获得'元素时强制转换为E.这样你就可以实例化(例如Object [] list = new Object [20];
  3. E在类声明中两次,因为你正在扩展一个类AbstractList并且你正在通过E对你的类进行参数化。例如,你可以这样做。
  4. 以下内容:

    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());
        }
    
    }
    

答案 1 :(得分:0)

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

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

你的方法根本就是错误的,所以我建议你阅读一些关于Java和面向对象编程的初学者文章。从您的代码来看,您似乎对OOP的实际存在一些误解。