我有三个接口:
public interface Combinable<V> {
V add(V other);
}
public interface Sublistable<V> {
boolean hasSublist();
List<V> getSublist();
void setSublist(List<V> sublist);
}
public interface HasUniqueIdentifier {
String getUniqueIdentifier();
}
和 4 个实现部分或全部这些接口的类:
public class Grandparent implements HasUniqueIdentifier,
Sublistable<Parent>,
Combinable<Grandparent>
{ List<Parent> sublist; ... }
public class Parent implements HasUniqueIdentifier,
Sublistable<Child>,
Combinable<Parent>
{ List<Child> sublist; ... }
public class Child implements HasUniqueIdentifier,
Sublistable<Grandchild>,
Combinable<Child>
{ List<Grandchild> sublist; ... }
public class Grandchild implements HasUniqueIdentifier,
Combinable<Grandchild>
{ }
我想要一个通用方法来执行以下操作:
public <V, T extends HasUniqueIdentifier & Combinable<T> & Sublistable<V>>
List<T> combine(List<T> items) {
Multimap<String, T> similarItemMap = HashMultimap.create();
for (T item: items) {
similarItemMap.put(item.getUniqueIdentifier(), item);
}
List<T> output = new ArrayList<T>();
for (Collection<T> similarCollection : similarItemMap.asMap().values()) {
List<T> similarItems = Lists.newArrayList(similarCollection);
T source = similarItems.get(0);
for (int i = 0; i < similarItems.size(); i++) {
source = source.add(similarItems.get(i));
}
output.add(source);
}
for (T item : output) {
if (item.hasSublist()) {
item.setSublist(combine(item.getSublist));
}
}
return output;
}
意识到这可能会创建一个无限循环(除非底层类 - 孙子 - 实现了 Sublistable 和 sethasSublist() { return false; }
或其他东西),以及这种方法对泛型有点疯狂的事实,我不得不问:是否有一些我可以稍微重写一下,以便我可以以这种方式调用该方法:
combine(listOfGrandparents)
还是我应该放弃这是一种方法并尝试以更好的方式对其进行重构?
编辑:
为了更好地解释我正在尝试做什么,我有一个 type 对象列表A
。每个对象a
都有一个类型为 的对象列表B
。每个对象b
都有一个 type 对象的列表C
,依此类推,直到最终 type T
(对于某些不同级别的T
)不再有子列表。
每种类型基本上都需要为“合并”或“组合”方法做三件事:
item.getUniqueIdentifier()
使用方法将所有“喜欢”的项目收集到一个容器中- 将所有相似的项目合并为一个项目,使用
source.add(other)
方法 - 如果该项目有子列表,请在子列表上进行合并。
n
由于每个项目的行为都非常相似,如果我可以使用单个方法而不是必须有方法,每种类型都有一个方法,那就太好了。不幸的是,由于没有一种类型可以保证是相同的(除了实现了上面给出的部分或全部接口之外),创建一个泛型方法被证明是困难的。有没有办法做到这一点,我错过了?
编辑2: 我找到了一种有效的方法。基本上,它会变成这样:
public <V extends HasUniqueIdentifier & Combinable<V>,
T extends HasUniqueIdentifier & Combinable<T>>
List<T> combine(List<T> items) {
Multimap<String, T> similarItemMap = HashMultimap.create();
for (T item: items) {
similarItemMap.put(item.getUniqueIdentifier(), item);
}
List<T> output = new ArrayList<T>();
for (Collection<T> similarCollection : similarItemMap.asMap().values()) {
List<T> similarItems = Lists.newArrayList(similarCollection);
T source = similarItems.get(0);
for (int i = 0; i < similarItems.size(); i++) {
source = source.add(similarItems.get(i));
}
output.add(source);
}
for (T item : output) {
if (item instanceof Sublistable<?>) {
@SuppressWarnings("unchecked")
Sublistable<V> sublistableItem = ((Sublistable<V>)sublistableItem);
if (sublistableItem.hasSublist()) {
sublistableItem.setSublist(combine(sublistableItem.getSublist));
}
}
}
return output;
}
不幸的是,这种方法需要 a@SupressWarnings
和 a instanceof
,如果可能的话我想避免。不过,我还没有找到其他任何东西。