在末尾重新定义了问题
--------------------------------------------
我必须编写两个泛型方法,以筛选泛型类型的集合。
第一个removeDuplicates和来自Collection<的可选空?扩展对象>。
第二个removeDuplicates和可选的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来筛选惟一的、清除原始集合并添加哈希集的所有条目。
首先,我试图通过流处理和使用lambda表达式来解决这个问题,但在这里我也找到了使用collect()来处理的问题。
首先,我尝试了流化和使用lambda表达式,但没有
很管用,但我相信一定有更好的办法。
第一种方法是从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( ),并根据inputtype创建泛型类型。问题是为输出集合保留输入集合的类型。
让我重新表述并简化这个问题,也许我不应该围绕着我想要做的事情写那么多。有任何有用的提示和提示,但核心问题没有得到解决
private <T extends Collection> T doFilter(T pCollection, ....
{
/** removed code for simplifing **/
return pCollection.stream()
/*.filter(....)*/
.collect( Collectors.toCollection( ?>> T <<?? ) );
}有人能告诉我如何收集(Collectors.toCollection(T))在一个具有通用类型的λ中吗?
因此,列表=> doFilter() =>列表
ArrayList => doFilter() => ArrayList
设置=> doFilter() =>集
LinkedHashSet => doFilter() => LinkedHashSet
T => doFilter() => T
……
发布于 2018-11-06 12:16:40
使用java 8流API确实会带来更清晰的实现:
public <T extends Collection<Object> T removeDuplicatesFromCollectionAndFilterNull(T collection) {
return collection.stream()
.filter(Objects::isNull) // Method Reference to Objects.isNull(object)
.collect(Collectors.toSet()); // Collect to set to remove duplicates
}类似的方法也可以用来解决第二个问题。请注意,collection方法不使用lambda来创建集合(而且T::new不会工作,因为Java不知道该方法是否有默认构造函数),而是一个收集器。这个指南可能会有帮助。
发布于 2018-11-06 12:23:51
您可以在流上使用distinct()方法
Collection<String> list = Arrays.asList("A", "B", "C", "D", "A", "B", "C");
// Get collection without duplicate i.e. distinct only
List<String> distinctElements =
list.stream().distinct().collect(Collectors.toList());这将返回所有非null的不一致元素:
public <T extends Collection<Object>> T removeDuplicatesFromCollection(T collection) {
return collection.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
}您还可以在供应商中使用此示例:
public static <T,U extends Collection<T>> U removeDuplicatesFromCollection(Iterable<T> iterable , Supplier<U> collectionType) {
return StreamSupport.stream(iterable.spliterator(),false).filter(Objects::nonNull).distinct().collect(Collectors.toCollection(collectionType));
}
List<String> strings = Arrays.asList("A","B",null,"B");
removeDuplicatesFromCollection(strings, ArrayList::new).forEach(System.out::println);发布于 2018-11-06 12:40:38
我认为主要的问题是以某种方式知道您正在处理的特定类型的集合,因此您可以创建这个特定类型的新集合,并将过滤后的值添加到其中。更改参数是错误的做法,即不应该修改接收到的集合。
因此,我将使用Supplier<T>作为工厂来创建特定的集合:
private <T extends Collection<C>, C> T removeDuplicatesFromCollection(
T collection,
boolean skipNull,
Supplier<? extends T> factory) {
if (collection == null) return null;
// Remove duplicates, but keep insertion order (that's what LinkedHashSet is for)
Set<C> noDuplicates = new LinkedHashSet<>(collection);
// Remove nulls from the set if the flag is on
if (skipNull) noDuplicates.removeIf(Objects::isNull);
// Use the factory to create an empty instance of the collection
T newCollection = factory.get();
// Add the no duplicates set, possibly without nulls
newCollection.addAll(noDuplicates);
return newCollection;
}现在,您可以按照以下方式使用上面的方法:
List<Integer> list = Arrays.asList(1, 2, 3, null, 5, 6, 1);
ArrayList<Integer> noDupsNoNulls = removeDuplicatesFromCollection(
list,
true,
ArrayList::new); // [1, 2, 3, 5, 6]编辑:--如果您已经有了对每个具体集合类型执行相同操作的方法,比如一个用于List<C>,另一个用于Set<C>等等,则不需要将所有调用都更改为这些方法。您所需要做的就是更改它们的实现,以便它们现在指向上面的新方法。
例如,假设您已经有了以下方法:
private <C> HashSet<C> removeDuplicatesFromCollection(
HashSet<C> collection,
boolean skipNull) {
// .....
}您可以将其更改如下:
private <C> HashSet<C> removeDuplicatesFromCollection(
HashSet<C> collection,
boolean skipNull) {
return removeDuplicatesFromCollection(collection, skipNull, HashSet::new);
}如果您有另一个用于ArrayList的方法
private <C> ArrayList<C> removeDuplicatesFromCollection(
ArrayList<C> collection,
boolean skipNull) {
// .....
}您可以将其更改如下:
private <C> ArrayList<C> removeDuplicatesFromCollection(
ArrayList<C> collection,
boolean skipNull) {
return removeDuplicatesFromCollection(collection, skipNull, ArrayList::new);
}https://stackoverflow.com/questions/53171532
复制相似问题