Я решаю алгоритмические проблемы и хочу написать пользовательские функции и предикаты, которые можно применять к коллекциям. Недавно я начал использовать Google Collections, и это просто замечательно для этой задачи.
Я хочу использовать BigInteger и BigDecimal таким же образом, как и любые другие числа. Не задумываясь над тем, как это сделать, я решил создать дополнительный уровень абстракции (класс E).
Если неясно, что я пытаюсь сделать, вот пример:
I.range(1,999).multiplication(I.range(1,999)).palindromes().max().echo(2);
- возврат коллекции из последовательности 1: 999 (x2)
- возвращает 2 коллекции для каждого элемента с помощью метода times () transform
- возвращает коллекцию каждого предмета, прошедшего фильтр палиндромов
- вернуть максимальный элемент E <?> Из 3. result
- вернуть элемент E <?> И вызвать метод toString с основанием 2 (двоичным) и вывести его на экран
Класс E определяется как:
public class E<T extends Number & Comparable<? super T>> extends Number implements Comparable<E<T>> {//...
Класс C определяется как:
public class C<T extends E<NC>, NC extends Number & Comparable<? super NC>> implements Collection<T> {
Это то, что я хочу сделать, работая в классе C.
public Collection<T> multiplication(T value) {
return Collections2.transform(this, new Function<T, T>() {
@Override
public T apply(T in) {
return in.times(value);
}
});
}
Прежде чем я использовал следующий код, в классе E
/** Multiplies 2 numbers */
public E<?> times(E<?> elem) {
if (this.value == null || elem.value == null) return E.Null();
if (this.value instanceof Integer) {
return E.with(I, this.intValue() * elem.intValue());
} else if (this.value instanceof Long) {
return E.with(L, this.longValue() * elem.longValue());
} else if (this.value instanceof Float) {
return E.with(F, this.floatValue() * elem.floatValue());
} else if (this.value instanceof Double) {
return E.with(D, this.doubleValue() * elem.doubleValue());
} else if (this.value instanceof BigInteger) {
return E.with(BI, this.BigIntegerValue().multiply(
elem.BigIntegerValue()));
} else if (this.value instanceof BigDecimal) { return E.with(BD,
this.BigDecimalValue().multiply(elem.BigDecimalValue())); }
return E.Null();
}
Что я должен изменить, чтобы написание пользовательских функций и предикатов включало минимальное количество 'suckiness' .
Edit:
Хорошо, изменил C на:
public class C<T extends E<?>> extends ArrayList<T> {
И только подавленные универсальные предупреждения о подстановочных символах типа
public Collection<T> multiplication(Collection<T> value) {
C<T> result = new C<T>();
for (T t : value)
result.addAll(multiplication(t));
return result;
}
public Collection<T> multiplication(final T value) {
return Collections2.transform(this, new Function<T, T>() {
@SuppressWarnings("unchecked")
@Override
public T apply(T in) {
return (T) in.times(value);
}
});
}
Так что, если типы совпадают, это работает.