Java:有地图功能吗?

发布于 2024-09-26 19:51:13 字数 148 浏览 6 评论 0原文

我需要一个 map 函数。 Java 中已经有类似的东西了吗?

(对于那些想知道的人:我当然知道如何自己实现这个简单的功能......)

I need a map function. Is there something like this in Java already?

(For those who wonder: I of course know how to implement this trivial function myself...)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

末蓝 2024-10-03 19:51:13

从 Java 8 开始,JDK 中有一些标准选项可以执行此操作:

Collection<E> in = ...
Object[] mapped = in.stream().map(e -> doMap(e)).toArray();
// or
List<E> mapped = in.stream().map(e -> doMap(e)).collect(Collectors.toList());

请参阅 java.util.Collection.stream()java.util.stream.Collectors.toList()

Since Java 8, there are some standard options to do this in JDK:

Collection<E> in = ...
Object[] mapped = in.stream().map(e -> doMap(e)).toArray();
// or
List<E> mapped = in.stream().map(e -> doMap(e)).collect(Collectors.toList());

See java.util.Collection.stream() and java.util.stream.Collectors.toList().

晚雾 2024-10-03 19:51:13

从 java 6 开始,JDK 中没有函数的概念。

Guava 有一个 Function 界面以及
Collections2.transform(Collection, Function)
方法提供您需要的功能。

示例:

// example, converts a collection of integers to their
// hexadecimal string representations
final Collection<Integer> input = Arrays.asList(10, 20, 30, 40, 50);
final Collection<String> output =
    Collections2.transform(input, new Function<Integer, String>(){

        @Override
        public String apply(final Integer input){
            return Integer.toHexString(input.intValue());
        }
    });
System.out.println(output);

输出:

[a, 14, 1e, 28, 32]

如今,Java 8 中实际上有了一个地图函数,因此我可能会以更简洁的方式编写代码:

Collection<String> hex = input.stream()
                              .map(Integer::toHexString)
                              .collect(Collectors::toList);

There is no notion of a function in the JDK as of java 6.

Guava has a Function interface though and the
Collections2.transform(Collection<E>, Function<E,E2>)
method provides the functionality you require.

Example:

// example, converts a collection of integers to their
// hexadecimal string representations
final Collection<Integer> input = Arrays.asList(10, 20, 30, 40, 50);
final Collection<String> output =
    Collections2.transform(input, new Function<Integer, String>(){

        @Override
        public String apply(final Integer input){
            return Integer.toHexString(input.intValue());
        }
    });
System.out.println(output);

Output:

[a, 14, 1e, 28, 32]

These days, with Java 8, there is actually a map function, so I'd probably write the code in a more concise way:

Collection<String> hex = input.stream()
                              .map(Integer::toHexString)
                              .collect(Collectors::toList);
以为你会在 2024-10-03 19:51:13

有一个很棒的库,名为 Functional Java,它可以处理许多您希望 Java 具有但它没有的功能。再说一次,还有一种奇妙的语言 Scala,它可以完成 Java 应该做但没有做的所有事情,同时仍然与为 JVM 编写的任何内容兼容。

There is a wonderful library called Functional Java which handles many of the things you'd want Java to have but it doesn't. Then again, there's also this wonderful language Scala which does everything Java should have done but doesn't while still being compatible with anything written for the JVM.

耳钉梦 2024-10-03 19:51:13

使用番石榴的 Collections2.transform() 时要非常小心。
这种方法的最大优点也是它最大的危险:它的惰性。

查看 Lists.transform() 的文档,我相信它也适用于 Collections2.transform()

该函数是延迟应用的,在需要时调用。这是必要的
返回的列表是一个视图,但这意味着该函数
将多次应用于批量操作,例如
List.contains(java.lang.Object) 和 List.hashCode()。为此
性能好,功能应该很快。为了避免懒惰评估
返回的列表不需要是视图,复制返回的列表
进入您选择的新列表。

另外,在 Collections2.transform() 的文档中,他们提到您可以获得实时视图,源列表中的更改会影响转换后的列表。如果开发人员没有意识到它的工作方式,这种行为可能会导致难以跟踪的问题。

如果您想要一个更经典的“地图”,它只会运行一次,那么您最好使用 FluentIterable,同样来自Guava,它的操作要简单得多。这是谷歌的示例:

FluentIterable
       .from(database.getClientList())
       .filter(activeInLastMonth())
       .transform(Functions.toStringFunction())
       .limit(10)
       .toList();

transform() 这里是地图方法。它使用相同的 Function<> “回调”为Collections.transform()。不过,您返回的列表是只读的,请使用 copyInto() 来获取读写列表。

否则,当 java8 推出 lambda 时,这就会过时。

Be very careful with Collections2.transform() from guava.
That method's greatest advantage is also its greatest danger: its laziness.

Look at the documentation of Lists.transform(), which I believe applies also to Collections2.transform():

The function is applied lazily, invoked when needed. This is necessary
for the returned list to be a view, but it means that the function
will be applied many times for bulk operations like
List.contains(java.lang.Object) and List.hashCode(). For this to
perform well, function should be fast. To avoid lazy evaluation when
the returned list doesn't need to be a view, copy the returned list
into a new list of your choosing.

Also in the documentation of Collections2.transform() they mention you get a live view, that change in the source list affect the transformed list. This sort of behaviour can lead to difficult-to-track problems if the developer doesn't realize the way it works.

If you want a more classical "map", that will run once and once only, then you're better off with FluentIterable, also from Guava, which has an operation which is much more simple. Here is the google example for it:

FluentIterable
       .from(database.getClientList())
       .filter(activeInLastMonth())
       .transform(Functions.toStringFunction())
       .limit(10)
       .toList();

transform() here is the map method. It uses the same Function<> "callbacks" as Collections.transform(). The list you get back is read-only though, use copyInto() to get a read-write list.

Otherwise of course when java8 comes out with lambdas, this will be obsolete.

倾城泪 2024-10-03 19:51:13

这是另一个您可以使用地图的功能库:http://code.google.com/p/完全懒惰/

sequence(1, 2).map(toString); // lazily returns "1", "2"

This is another functional lib with which you may use map: http://code.google.com/p/totallylazy/

sequence(1, 2).map(toString); // lazily returns "1", "2"
明媚殇 2024-10-03 19:51:13

尽管这是一个老问题,我想展示另一个解决方案:

只需使用 java 泛型和 java 8 流定义您自己的操作:

public static <S, T> List<T> map(Collection<S> collection, Function<S, T> mapFunction) {
   return collection.stream().map(mapFunction).collect(Collectors.toList());
}

您可以编写如下代码:

List<String> hex = map(Arrays.asList(10, 20, 30, 40, 50), Integer::toHexString);

Even though it's an old question I'd like to show another solution:

Just define your own operation using java generics and java 8 streams:

public static <S, T> List<T> map(Collection<S> collection, Function<S, T> mapFunction) {
   return collection.stream().map(mapFunction).collect(Collectors.toList());
}

Than you can write code like this:

List<String> hex = map(Arrays.asList(10, 20, 30, 40, 50), Integer::toHexString);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文