首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >方法在集合上创建转换功能。

方法在集合上创建转换功能。
EN

Code Review用户
提问于 2014-04-23 11:22:14
回答 1查看 89关注 0票数 10

我已经用Java 8编写了一些简单的使用方法,我想知道在这些方法上还可以改进什么:

代码语言:javascript
运行
复制
public static <E, R, C extends Collection<? extends R>> C transform(final Collection<E> collection, final Function<? super E, ? extends R> mapper) {
    try {
        Objects.requireNonNull(collection);
        Objects.requireNonNull(mapper);
        Class<? extends Collection> clazz = collection.getClass();
        @SuppressWarnings("unchecked") Collection<Object> returnCollection = clazz.newInstance();
        collection.stream().map(mapper).forEach(returnCollection::add);
        @SuppressWarnings("unchecked") C genericReturnCollection = (C)returnCollection;
        return genericReturnCollection;
    } catch (InstantiationException | IllegalAccessException ex) {
        throw new RuntimeException(ex);
    }
}

public static <E, R, C extends Collection<R>> C transform(final Collection<E> collection, final Function<? super E, ? extends R> mapper, final Supplier<C> collectionSupplier) {
    Objects.requireNonNull(collection);
    Objects.requireNonNull(mapper);
    Objects.requireNonNull(collectionSupplier);
    return collection.stream().map(mapper).collect(Collectors.toCollection(collectionSupplier));
}

它们的目的是提供与List.replaceAll()方法类似的功能,但随后允许映射的类型与原始类型不同。因此,它应该在static工厂类中,因为它总是需要创建一个新集合。

一些示例代码:

代码语言:javascript
运行
复制
LinkedList<Integer> linkedList = new LinkedList<>();
linkedList.add(5);
linkedList.add(10);
linkedList.add(15);
LinkedList<String> resultList = transform(linkedList, i -> (i + 1) + "-" + i);

代码语言:javascript
运行
复制
LinkedList<Integer> linkedList = new LinkedList<>();
linkedList.add(5);
linkedList.add(10);
linkedList.add(15);
LinkedList<String> resultList = transform(linkedList, i -> (i + 1) + "-" + i, LinkedList::new);

两者都有如下输出:

6-5 11-10 16-15

我知道,以一个transform作为参数的Supplier<C>显然要好得多,但是为了方便起见,只有一个函数的单参数版本要好得多。

EN

回答 1

Code Review用户

回答已采纳

发布于 2014-04-23 11:36:18

我认为供应商-少的选择是一个非常坏的选择。考虑以下代码:

代码语言:javascript
运行
复制
transform(linkedList.sublist(0, linkedList.size() / 2), i -> (i + 1) + "-" + i);

或者,没有有意义的默认构造函数的任何其他集合:

代码语言:javascript
运行
复制
transform(Arrays.asList(argv), a -> a.toLowerCase());

该代码将导致比添加供应商所需的小需求更令人头疼的问题。

当没有供应商时,映射的泛型也会中断,因为返回列表的实际类型应该更具体.

失去第一个静态方法。

第二种方法看起来很好,除了参数的排序。我会让供应商处于中间位置,而不是最后一个论点(我会引入一些新的路线,使其不那么长的一条线):

代码语言:javascript
运行
复制
public static <E, R, C extends Collection<R>> C transform(
          final Collection<E> collection,
          final Supplier<C> collectionSupplier,
          final Function<? super E, ? extends R> mapper) {
    ....
}

这个顺序的逻辑读取更好,拿这个集合,映射到那个集合,并使用这个函数来完成它……也许没什么大不了的.?

用例对我来说似乎读得更好:

代码语言:javascript
运行
复制
List<String> lcargs = transform(Arrays.asList(args), ArrayList::new, a -> a.toLowerCase());
票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/47967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档