Как вернуть число, используя дженерики в Java?

У меня есть простой класс, как показано ниже, но у меня есть вопрос об использовании дженериков для возврата значения.

import java.util.ArrayList;
public class Box<T extends Number> {
    private ArrayList<T> list;
    public Box(){
        list = new ArrayList<T>();
    }
    public T get(int i){
        if(i <list.size())
            return list.get(i);
        else
            return 0; // Problem
    }
}

Я должны получить 0 (или 0.0 - это зависит от значения T), когда i null. Как я могу кодировать это правильно, чтобы сделать это?

4 ответов


Если вы действительно хотите вернуть 0 по умолчанию, вы можете сделать что-то вроде этого:

public abstract class Box<T extends Number> {
    private List<T> list;

     public Box(){
        list = new ArrayList<T>();
    }

    public T get(int i){
        if(i <list.size())
            return list.get(i);
        else
            return getDefault();
    }

    protected abstract T getDefault();
}

затем есть реализация для каждого подтипа номера, который вы хотите поддержать, например

public class IntegerBox extends Box<Integer> {

    @Override
    protected Integer getDefault() {
        return 0;
    }
}

и

public class DoubleBox extends Box<Double> {

    @Override
    protected Double getDefault() {
        return 0D;
    }
}

etc.

хорошей особенностью этого является то, что он может возвращать любое значение по умолчанию, а не только ноль...и тот же принцип будет работать для любого типа объектов, а не только для чисел.


Если вам действительно нужен ваш Box чтобы вернуть нулевое значение или значение по умолчанию, которое, когда get не находит совпадения, вы можете иметь параметр конструктора для нуля или по умолчанию типа T.

затем верните это значение по умолчанию в свой get метод.

пример:

public class Box<T extends Number> {
    private ArrayList<T> list;
    private T defaultValue;
    public Box( T defaultValue){
        list = new ArrayList<T>();
        this.defaultValue = defaultValue;
    }
    public T get(int i){
        if(i <list.size())
            return list.get(i);
        else
            return defaultValue;
    }
}

0 это int и дженерики работают только со ссылками на объекты (не примитивные типы). Способ исправить ваш код будет возвращать .

public T get(int i){
    if(i <list.size()) {
        return list.get(i);
    }
    return null; // Problem solved
}

Я должны получить 0 (или 0.0 - это зависит от T), когда i null

примите во внимание, что темы презентации как показать 0 пользователю должны обрабатываться классами / методами, которые показывают данные, а не этими методами. Это значит,нет способа вернуть 0, когда вы должны вернуть ссылку на объект.


вы не можете сделать это без создания подклассов для всех типов и без параметризации и явной проверки типа. И это нормально: я мог бы создать тип

public StrictlyPositiveInteger implements Number

это даже не имеет значения 0, а затем do

Box<StrictlyPositiveInteger> box = new Box<>();

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