public double sum(TreeNode root){
Queue<TreeNode> queue = new ArrayDeque<>();
double sum = 0;
if (root!=null){
queue.add(root);
}
while(!queue.isEmpty()){
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode current = queue.remove();
sum += current.value;
if (current.leftChild!=null)
queue.add(current.leftChild);
if (current.rightChild!=null)
queue.add(current.rightChild);
}
}
return sum;
}
Теперь мне нужно реализовать общее двоичное дерево поиска, которое может хранить в поле value узла либо Character, либо Integer, либо Double (если Character является общим параметром дерева, то его кодовая сумма ASCII будет возвращена из sum() метод).
И мне нужно выполнять различные операции, такие как sum() всех значений узла (также вставлять, удалять, искать, максимальное, минимальное и т. д.).
Но я застрял на том, чтобы сделать мою реализацию универсальной. В методе sum() выдает ошибку в строке
sum += current.value;
Оператор + не может быть применен к T.
Как я могу решить эту проблему?
Не могли бы вы добавить сюда остальные ваши коды?




Арифметические операторы нельзя использовать с произвольным типом, они применимы только к числовым примитивам и их типам-оболочкам. Поэтому, если вам нужно обобщить свою логику, это не тот путь.
Вместо этого вы можете определить поле типа BiFunction, которое представляет собой функцию, ожидающую два аргумента, на уровне вашего Tree класса (или любого другого его имени). И используйте это BinaryOperator для накопления значений узлов при обходе дерева.
На основании этой цитаты:
если
Characterявляется общим параметром Дерева, то его кодовая сумма ASCII будет возвращена из методаsum()
Я предполагаю, что вам нужно сохранить тип возвращаемого значения метода sum() как double. Поскольку в соответствии с требованиями вашего задания необходимо поддерживать только три универсальных типа: Character, Integer или Double, это выполнимо.
Для этого BiFunction, упомянутый выше, может быть определен как BiFunction<T,Double,Double>, где первые два общих параметра T и Double обозначают типы входящих параметров функции, а последний тип Double указывает тип возвращаемого значения. Вот примеры реализации такой функции:
BiFunction<Double, Double, Double> intMerger = Double::sum;
BiFunction<Integer, Double, Double> intMerger = (i, d) -> i + d;
BiFunction<Character, Double, Double> intMerger = (c, d) -> c + d;
Кроме того, поскольку вам нужно выполнять такие операции, как бинарный поиск в вашем универсальном дереве, вам нужно либо определить общий параметр T как расширяющий Comparable интерфейс, либо предоставить Comparator (в противном случае вы не сможете определить, какое значение больше/меньше при реализации бинарный поиск или поиск минимального/максимального значения). Поскольку все типы, которые должны поддерживаться, сопоставимы, вы можете использовать первый вариант и определить параметр Generic как T extends Comparable<T>, что на простом английском языке означает: что-то, что умеет сравнивать себя.
В результате у вас может получиться что-то вроде этого:
public class MyTree<T extends Comparable<T>> {
private final BiFunction<T, Double, Double> merger;
public MyTree(BiFunction<T, Double, Double> merger) {
this.merger = merger;
}
public double sum(TreeNode<T> root) {
double total = 0;
if (root == null) return total;
Queue<TreeNode<T>> queue = new ArrayDeque<>();
queue.add(root);
while (!queue.isEmpty()) {
int size = queue.size();
TreeNode<T> current = queue.remove();
total = merger.apply(current.value, total);
if (current.leftChild != null) queue.add(current.leftChild);
if (current.rightChild != null) queue.add(current.rightChild);
}
return total;
}
private static class TreeNode<T extends Comparable<T>> {
private T value;
private TreeNode<T> leftChild;
private TreeNode<T> rightChild;
// constructor, etc.
}
}
Пример использования:
MyTree<Double> myTree1 = new MyTree<>(Double::sum);
MyTree<Integer> myTree2 = new MyTree<>((i, d) -> i + d);
MyTree<Character> myTree3 = new MyTree<>((c, d) -> c + d);
Примечание: если то, что я говорил о введении функции, кажется вам чуждым, взгляните на этот учебник, предоставленный Oracle.
На самом деле атрибут/свойство value класса TreeNode является общим.