确切地说,我试图压扁一棵树,并且我一直试图使用泛型函数在泛型类中获取私有属性的值。
我已经附加了类来显示树的结构。但它看起来像这样:
/|\
1 | 6
/|\
5 4 9
我打算在最后粘贴我的尝试。首先,让我介绍一下这些课程:
Triple只存储三个相同类型的值。
public class Triple<V> {
private final V l, m, r;
public Triple(V l, V m, V r) {
this.l = l;
this.m = m;
this.r = r;
}
public V left() { return l; }
public V middle() { return m; }
public V right() { return r; }
}
直接的界面:
public interface Function<P, R> {
R apply(P p);
}
现在,对于一个棘手的课程。这个只是一种存储两种类型值的EitherOr的类型,但不能同时存储两种类型。
public class EitherOr<A,B> {
// Constructs a left-type EitherOr
public static <A> EitherOr left(A a) {
return new EitherOr(a, null);
}
// Constructs a right-type EitherOr
public static <B> EitherOr right(B b) {
return new EitherOr(null, b);
}
private final A a;
private final B b;
private EitherOr(A a, B b) {
this.a = a; this.b = b;
}
public<T> T ifLeft(Function<A,T> f) {
return f.apply(a);
}
public<T> T ifRight(Function<B,T> f) {
return f.apply(b);
}
public boolean isLeft() {
return b == null;
}
}
我知道这已经很久了,但请耐心等待。该类实现树结构。
public interface Tree<T> {
EitherOr<T, Triple<Tree<T>>> get();
static final class Leaf<T> implements Tree<T> {
public static <T> Leaf<T> leaf (T value) {
return new Leaf<T>(value);
}
private final T t;
public Leaf(T t) { this.t = t; }
@Override
public EitherOr<T, Triple<Tree<T>>> get() {
return EitherOr.left(t);
}
}
static final class Node<T> implements Tree<T> {
public static <T> Tree<T> tree (T left, T middle, T right) {
return new Node<T>(Leaf.leaf(left), Leaf.leaf(middle), Leaf.leaf(right));
}
private final Triple<Tree<T>> branches;
public Node(Tree<T> left, Tree<T> middle, Tree<T> right) {
this.branches = new Triple<Tree<T>>(left, middle, right);
}
@Override
public EitherOr<T, Triple<Tree<T>>> get() {
return EitherOr.right(branches);
}
}
}
好的。这是我对扁平化的想法:
public class MyFlattenTree<T> implements FlattenTree<T> {
public List<T> flattenInOrder(Tree<T> tree) {
List<T> list = new ArrayList<T>();
EitherOr<T, Triple<Tree<T>>> EitherOr;
EitherOr = tree.get();
// it is a leaf
if (EitherOr.isLeft()) {
// This is where the problem lies
// I don't how to get the value using a function f
list.add((T) EitherOr.ifLeft(f));
return list;
}
else {
// basically recursively go through the tree somehow
}
return null;
}
}
正如我所说,我一直试图使用Function接口检索EitherOr类中的值。我正在考虑实现Function接口并为&#34; apply&#34;编写一个函数。只是获得了价值,但我不知道该怎么做。任何帮助,将不胜感激。谢谢!
答案 0 :(得分:3)
所以,这是你的flattenInOrder
方法:
public List<T> flattenInOrder(final Tree<T> tree) {
final EitherOr<T, Triple<Tree<T>>> EitherOr = tree.get();
if (EitherOr.isLeft()) {
return Collections.singletonList(EitherOr.ifLeft(this.ifLeftFunction));
}
return EitherOr.ifRight(this.ifRightFunction);
}
很简单,假设:
ifLeftFunction
会产生一个元素(因为EitherOr<T, Triple<Tree<T>>>
只有一个T
elem',如果它是“left”)......和:
ifRightFunction
会产生一系列元素(因为EitherOr<T, Triple<Tree<T>>>
有一个T
elems'列表,如果它是“正确的”)现在让我们看看这些功能:
ifLeftFunction
是......基本的。我想从...... T
中提取T
。
final Function<T, T> ifLeftFunction = new Function<T, T>() {
@Override
public T apply(final T t) {
return t;
}
};
ifRightFunction
稍微复杂一点:它必须是递归的,并从它正在浏览的树中收集所有T
:
final Function<Triple<Tree<T>>, List<T>> ifRightFunction = new Function<Triple<Tree<T>>, List<T>>() {
@Override
public List<T> apply(final Triple<Tree<T>> t) {
final List<T> res = new ArrayList<>();
res.addAll(MyFlattenTree.this.flattenInOrder(t.left()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.middle()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.right()));
return res;
}
};
而且......你已经完成了!
示例工作代码:
public class MyFlattenTree<T> {
private final Function<Triple<Tree<T>>, List<T>> ifRightFunction = new Function<Triple<Tree<T>>, List<T>>() {
@Override
public List<T> apply(final Triple<Tree<T>> t) {
final List<T> res = new ArrayList<>();
res.addAll(MyFlattenTree.this.flattenInOrder(t.left()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.middle()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.right()));
return res;
}
};
private final Function<T, T> ifLeftFunction = new Function<T, T>() {
@Override
public T apply(final T t) {
return t;
}
};
public static void main(final String[] args) {
final Tree<String> tree = new Node<>(new Leaf<>("1"), new Node<>(new Leaf<>("5"), new Leaf<>("4"), new Leaf<>("9")), new Leaf<>("6"));
System.out.println(new MyFlattenTree<String>().flattenInOrder(tree));
}
public List<T> flattenInOrder(final Tree<T> tree) {
final EitherOr<T, Triple<Tree<T>>> EitherOr = tree.get();
if (EitherOr.isLeft()) {
return Collections.singletonList(EitherOr.ifLeft(this.ifLeftFunction));
}
return EitherOr.ifRight(this.ifRightFunction);
}
}
请注意,我在Tree
方法中以您的问题为例创建了您正在展示的确切main
:
public static void main(final String[] args) {
final Tree<String> tree = new Node<>(new Leaf<>("1"), new Node<>(new Leaf<>("5"), new Leaf<>("4"), new Leaf<>("9")), new Leaf<>("6"));
System.out.println(new MyFlattenTree<String>().flattenInOrder(tree));
}
输出:[1, 5, 4, 9, 6]
干杯;)