Когда создавать универсальный класс - PullRequest
1 голос
/ 18 января 2012

Я не использовал дженерики раньше, и мне интересно, когда я должен их использовать и каковы преимущества. Я думаю, что это может быть уместно для коллекции, которую я создал, так как java всегда также использует обобщенные значения для коллекций, но если я вызываю созданные мной методы, тип уже установлен в функции, поэтому в любом случае это приведет к ошибке. Когда я должен использовать универсальный класс? Не могли бы вы привести пример, потому что я не уверен, как его использовать. На данный момент мой код выглядит следующим образом:

public class NodeList {
  private static final int MAX_AMOUNT_OF_NODES = 12;
  private HashMap<String, Node> nodeList;

  public NodeList(){
    nodeList    = new HashMap<String, Node>(MAX_AMOUNT_OF_NODES);
  }

  public Node get(String id){
    return nodeList.get(id);
  }

  public boolean add(Node node){
    if(nodeList.size() <= MAX_AMOUNT_OF_NODES){
      nodeList.put(node.id, node);
      return true;
    }
    return false;
  }
}

Ответы [ 4 ]

2 голосов
/ 18 января 2012

Вы можете посмотреть на существующий API для руководства. Например, все коллекции являются общими. Это потому, что все коллекции содержат элементы типа.

Исходя из этого, имеет смысл использовать универсальные классы, когда вам придется снова и снова создавать один и тот же код для разных типов. Если вам нужно сделать это, дженерики могут предложить вам некоторую выгоду.

В качестве примера, документы - хорошее место для начала .

По этой ссылке первый пример кода:

public class Box<T> {

    // T stands for "Type"
    private T t;

    public void add(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }
}

Концептуально, есть класс Box, который будет содержать что-то. То, что оно содержит, не имеет значения, потому что тип определяется программистом. Экземпляр Box может содержать в основном все, что угодно. Когда программисту нужно создать поле, он / она указывает тип.

Box<SomeClass> myBox = new Box<SomeClass>();

Подумайте об этом так: если вы хотите создать общий ящик, который может содержать что угодно без генериков, вам придется

1) иметь поле f быть Object или
2) создать класс Box для каждого типа, который может содержать box.

При использовании дженериков вам нужен только один класс, и вы можете указать точный тип. Возможно, если вы что-то делаете, и ваш подход подразумевает 1 или 2 выше, лучше использовать дженерики.

1 голос
/ 18 января 2012

Если Node - это класс, который может содержать фрагмент данных определенного типа (например, String), то вы должны сгенерировать Node, а затем NodeList, чтобы предотвратить ошибки типа.

Если вы этого не сделаете, то вы оставляете это на усмотрение пользователя вашего NodeList, чтобы гарантировать, что она никогда не добавит Integer, когда список должен содержать только String с.Обобщение в первую очередь связано с обнаружением проблем типов во время компиляции , а не времени выполнения .

Это довольно просто сделать, изменив что-то вроде этого:

public class Node {
    Object data;
    //...
}

примерно так:

public class Node<T> {
    T data;
    //...
}

public class NodeList<T> {
    public Node<T> get(String id) {
        //...
    }

    public boolean add(Node<T> node) {
        //...
    }
}

Ваш NodeList выглядит так, как будто потенциально может иметь параметр второго типа для типа key , который вы сейчас ограничиваетеString.

0 голосов
/ 18 января 2012

Generics - это способ для Java заставить структуру данных коллекции (HashMap в вашем случае) принимать только объекты определенных типов. Это означает, что во время компиляции, если вы попробовали что-то вроде:

nodeList.add(1, new Node());

это не удастся и не скомпилируется, поскольку 1 не является объектом String. Как правило, это способ написать код более аккуратный.

Проверьте и эту ссылку: http://en.wikipedia.org/wiki/Generics_in_Java

0 голосов
/ 18 января 2012

Вы можете вводить как аргументы методов, так и сам класс.Вот пример из интерфейса Java java.util.List:

public interface List<E> {

//...

    boolean add(E e);

//...

}
...