Как элементы могут быть добавлены к подстановочному универсальному набору?

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

Function<Integer,Double> facts = x -> { return  ( x == 0)?1:x* facts.apply(x-1);};
BiFunction<Integer,Double,Double> factAcc= (x,acc) -> { return (x == 0)?acc:factAcc.apply(x- 1,acc*x);};
Function<Integer,Double> fact = x -> factAcc.apply(x,1.0) ;

public static void main(String[] args) {
   Test test = new Test();
   test.doIt();
}

 public void doIt(){
int val=70;
System.out.println("fact(" + val + ")=" + fact.apply(val));
}
}
16
задан erickson 28 July 2009 в 16:44
поделиться

3 ответа

Используйте это вместо этого:

1  public List<? extends Foo> getFoos()
2  {
3    List<Foo> foos = new ArrayList<Foo>(); /* Or List<SubFoo> */
4    foos.add(new SubFoo());
5    return foos;
6  }

, Как только Вы объявляете foos как List<? extends Foo>, компилятор не знает, что безопасно добавить SubFoo. Что, если ArrayList<AltFoo> был присвоен foos? Это было бы допустимым присвоением, но добавление SubFoo загрязнит набор.

29
ответ дан 30 November 2019 в 15:28
поделиться

Попытка:

public List<Foo> getFoos() {
    List<Foo> foos = new ArrayList<Foo>();
    foos.add(new SubFoo());
    return foos;
}

у универсального конструктора ArrayList должен быть определенный тип, который будет параметризован на, Вы не можете использовать'?' подстановочный знак там. Изменение инстанцирования к "новому ArrayList< Foo> ()', решил бы первую ошибку компиляции.

объявление 'foos' переменной может иметь подстановочные знаки, но так как Вы знаете точный тип, имеет больше смысла ссылаться на ту же информацию о типе там. Что Вы имеете, теперь говорит, что foos содержит некоторый определенный подтип Foo, но мы не знаем который. Добавление SubFoo не может быть позволено, так как SubFoo не является" всеми подтипами Foo ". Изменение объявления к 'List< Foo> foos =' решает вторую ошибку компиляции.

Наконец, я изменил бы тип возврата на 'List< Foo>'; так как клиенты этого метода не будут в состоянии сделать много с возвращенным значением, как в настоящее время определено. Необходимо редко использовать подстановочные знаки, в ответ вводит. Используйте подпись параметризованного метода в случае необходимости, но предпочтите, чтобы ограниченные типы только появились в аргументах метода, поскольку это оставляет ее до вызывающей стороны, которая может передать в определенных типах и действовать и их соответственно.

7
ответ дан 30 November 2019 в 15:28
поделиться

Следующее будет хорошо работать:

public List<? extends Foo> getFoos() {
    List<Foo> foos = new ArrayList<Foo>();
    foos.add(new SubFoo());
    return foos;
}
2
ответ дан 30 November 2019 в 15:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: