【问题标题】:Equivalent of Ruby #map or #collect in Java?相当于 Java 中的 Ruby #map 或 #collect?
【发布时间】:2015-12-20 11:26:01
【问题描述】:

假设我有一个数组movies = get_movies()

我经常在 ruby​​ 中使用 movies.map {|movie| movie.poster_image_url } 之类的。

在 Java 中我能做什么类似的事情?并且同样优雅、简洁和易读。我知道有无数种方法可以做到这一点,但如果有一种很好的方法可以让我不想使用 Groovy 或其他东西,请告诉我。我确信 Java 有一些很棒的方法来做这样的事情。

到目前为止,这是我使用来自https://github.com/holgerbrandl/themoviedbapi/ 的 TheMovieDB API Java 包装器的 Java 代码。

        TmdbMovies movies = new TmdbApi(BuildConfig.MOVIEDB_API_KEY).getMovies();
        MovieResultsPage results = movies.getPopularMovieList("en", 1);
        // The following line is RubyJava and needs to your help!
        results.getResults().map {|e| e.getPosterPath() };
        // or ... more RubyJava results.getResults().map(&:getPosterPath()); 

如果您了解很多 Java,但不熟悉 ruby​​,请多了解一些关于 Ruby 中的#map/#collect 的信息。 http://ruby-doc.org/core-1.9.3/Array.html#method-i-collect

到目前为止,我从快速浏览中看到的最接近的答案...https://planet.jboss.org/post/java_developers_should_learn_ruby

这些看起来也很近。 http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

这么多选择:Functional Programming in Java

这也是 Android ......有什么好东西可供 Android 开发人员开箱即用并让这种编程变得简单?这是一种函数式编程风格,对吧?

--

在得到诸如“for 循环没有任何问题”和(基本上)“语法不是一切”这样非常好的见解的回复后,我决定不再尝试让我的所有 Java 看起来都像 Ruby !我读了这篇文章,然后想象了另一个未来,“未来的我”做出了一大堆糟糕的风格决定:https://github.com/google/guava/wiki/FunctionalExplained

【问题讨论】:

  • 您正在通过results.getResults().stream().map(MovieResult::getPosterPath).collect(Collectors.toList()); 之类的方式查找 Java 8 的 java.util.stream。如果您正在执行一长串操作来摊销 .stream()/.collect(),或者如果您与 .parallel() 并行运行,则效果最佳。但实际上,for 循环并没有错……

标签: java android


【解决方案1】:

流上有map 方法,它接受一个方法参数。

collection.stream()
  .map(obj -> obj.someMethod())
  .collect(Collectors.toList()));

map 返回另一个流,因此为了检索您拥有的列表,请调用 collect 方法。

在帖子中解释太多,但您可以访问这个对我有很大帮助的链接:

http://winterbe.com/posts/2014/03/16/java-8-tutorial/

【讨论】:

  • 我可以进一步压缩吗?在 ruby​​ 中,您可以使用 movies.map{|movie| movie.link}movies.map(&:link)。有类似的东西吗?
  • 不幸的是,仅此而已。我能够将 lambda 表达式压缩这么多的唯一原因是因为我只有一个参数和一个语句。否则,它会看起来像这样:(obj1, obj2,...objn) -> { statements; } Java 8 通过允许您传递方法,在某种程度上使方法或函数成为一等公民。如果您发现 lambda 表达式过于冗长,您也可以尝试这样做,但此时它是微不足道的
  • 谢谢。还是很不错的。
  • 您可以使用YourObject::someMethod 之类的函数引用使其与%:link 相媲美。 @David:整个流的事情比 Ruby 或 Groovy 做的要好得多(由于惰性 eval),专注于语法并不是最重要的事情。
  • Util.Stream 只是从 java 1.8 (Java8) 开始,你不会在 Android 上得到这个(最早直到下一个谷歌 IO,IF 他们添加了对然后java8到Android)docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
【解决方案2】:

我认为 (a collections class).foreach() 是您想要的,需要 java8,并且经常使用 lambda 表达式来实现满足“foreach()”方法所需输入的类。

http://www.mkyong.com/java8/java-8-foreach-examples/


要解决您对这是 Android 的更改,那么不,您将不会获得 java8 类更改,例如 .foreach(),您可以通过使用 retrolambda android variant 获得 lambda 表达式。但这只会为您提供一些 Java8 的“语法”而不是“类”,您也无法访问 Streams 类。

【讨论】:

  • 听起来不错。有没有类似 forEach 的东西返回处理后的集合?希望我的问题有意义。我对 Java 的了解还不够,可能无法提出一个好问题。但我喜欢 ruby​​ 方法 #map 和 #collect 的地方在于它们返回处理后的集合。
  • 阅读我在 android 上解决此问题的编辑(剧透:对不起,哈哈)
  • foreach() 使用 Iterable/Iterator 接口/类,因此它可以就地修改集合,但它不返回任何内容。 docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html
  • 我可以将有价值的库添加到我的 Gradle 配置中吗?谷歌 Guava 是我听说过的一款适用于 fp 类型的东西...阅读有关 retrolambda 的更多信息...
  • 我不知道,我不使用太多功能。它很流行,但是 Java8 的实现不允许我在“函数式”语言中看到的那些特性,在这些特性中你甚至不知道参数的第二个或第三个参数,直到它被处理之后,等等。(我这种解释可能会“略微”偏离,因为我自己从来没有写过)。 Java8 的“函数式”编程主要只是语法糖
猜你喜欢
  • 2012-04-12
  • 2014-01-29
  • 2015-09-17
  • 2012-11-12
  • 1970-01-01
  • 2016-12-19
  • 2019-07-06
  • 1970-01-01
相关资源
最近更新 更多