【发布时间】:2018-11-06 12:03:34
【问题描述】:
最后改写问题
------------------------------------------
我必须编写两个泛型方法来过滤泛型类型的集合。
首先从 Collection。
Collection
private <T extends Collection<C>, C extends Object> T removeDuplicatesFromCollection(T collection, boolean skipNull)
{
if(collection == null)
{
return collection;
}
final HashSet<C> tmp = new HashSet<C>();
for(C element : collection)
{
if(element == null && skipNull)
{
continue;
}
else
{
tmp.add(element);
}
}
collection.clear();
collection.addAll(tmp);
return collection;
}
我不知道如何解决这个问题。所以我使用 HashSet 来过滤唯一性,清除原始集合并添加 hashset 的所有条目。
首先我尝试通过流式传输和使用 lambda 表达式来解决这个问题,但这里也遇到了需要使用 collect() 处理的问题
首先我通过流式传输和使用 lambda 表达式尝试了这个,但没有 g
它有效,但我相信一定有更好的方法。
第一种方法是从 Collection 中删除重复项和空条目。 我想用 lambda 指令和 apache StringUtils 再次过滤这个列表,但我不知道如何处理收集和泛型类型 T。
private <T extends Collection<String>> T removeDuplicationsFromStringCollection(T collection, boolean skipNull, boolean skipEmpty)
{
if(collection == null)
{
return collection;
}
T removedDuplicates = removeDuplicatesFromCollection(collection, skipNull);
if(removedDuplicates == null || !skipEmpty)
{
return removedDuplicates;
}
else
{
removedDuplicates.().filter(s -> StringUtils.isNotBlank(s)).collect(T::new); <== [X Cannot instantiate the type T ]
}
}
任何人都可以帮助完成这项工作吗? 如果有人对第一种方法有更好的解决方案,我也将不胜感激,因为我自己还没有完全满意。
非常感谢
------------[编辑]----
我不知道方法输入的集合类型,输出类型必须是输入类型的集合。 HashSet => 方法 => HashSet => 返回 ArrayList => 方法 => ArrayList => 返回
我不喜欢修改输入集合,但这是我保留集合类型的唯一方法。 问题不是在流式传输期间过滤列表,而是流式结束时的 collect(),并根据输入类型创建泛型类型。 问题是为输出集合保留输入集合的类型。
-------------[改写]-----
让我重新表述并简化这个问题,也许我不应该围绕我想做的事情写这么多。
有任何有用的提示和技巧,但核心问题没有解决
private <T extends Collection> T doFilter(T pCollection, ....
{
/** removed code for simplifing **/
return pCollection.stream()
/*.filter(....)*/
.collect( Collectors.toCollection( ?>> T <<?? ) );
}
谁能告诉我如何在泛型类型的 lambda 中收集(Collectors.toCollection(T))?
所以
列表 => doFilter() => 列表
ArrayList
Set
LinkedHashSet
[T => doFilter() => T]
....
【问题讨论】:
-
C extends Object是多余的,顺便说一句。一切都扩展了对象。 -
你说得对。我已经直接接管了。谢谢。
-
但是在这个改变之后,我没有用于 for 循环的 C,所以一切都必须是一个 Object,并且 Hashset 是用类型 obejct 实例化的。但我会确保列表包含一个通用对象。确定可以是对象,也可以是类车或客户。当然汽车和客户扩展了对象,一切都扩展了对象,但是我必须将所有内容都投射到对象中
-
Java 8 有“过滤”集合的想法,这就是你想要做的。 zeroturnaround.com/rebellabs/…。它不会修改原始集合(这通常是一种不好的做法),您只需将集合转换为流,然后应用 lambda 过滤掉您不想要的内容。
-
对于您的信息,我说这是一种不好的做法,因为无论谁为您的函数提供了集合可能不希望它被修改,您正在返回一个集合(相同的集合?一个新的?)和这种修改往往会导致代码导致并发问题。通常最好避免修改您的输入参数,除非您有特定的理由这样做(例如低内存嵌入式系统、大型数据集)