以Guava和Java为例,强制`Streams.zip`迭代每个元素的最佳方法是什么?

huangapple go评论111阅读模式
英文:

Whats the best way to force Streams.zip to iterate over each element (using Guava, Java)

问题

  1. 我正在尝试使用 Streams.zip 来创建一个映射map)。我不关心流返回的结果我只需要对每个元素执行 lambda 表达式以下是我的代码
  2. String x[] = {"a", "b"};
  3. String y[] = {"c", "d"};
  4. var data = new HashMap<String, String>();
  5. var myStream = Streams.zip(Arrays.stream(x), Arrays.stream(y),
  6. (arg1, arg2) -> { data.put(arg1, arg2); return 0; });
  7. var result = myStream.collect(Collectors.toList()); // 最好不要这行
  8. 如果没有 collect( ) 这行我就无法填充映射那么有没有更简单的方法来实现这一点呢我尝试过使用 count() 替代 collect但这会完全绕过 zip 操作
  9. 或者是否有更简单的单行解决方案不使用 Streams.zip来从两个列表中填充映射呢
英文:

I am trying to use Streams.zip to create a map. I don't care about the stream returned result, I just need the lambda to execute for each element. Here is my code

  1. String x[] = {&quot;a&quot;, &quot;b&quot;};
  2. String y[] = {&quot;c&quot;, &quot;d&quot;};
  3. var data = new HashMap&lt;String, String&gt;();
  4. var myStream = Streams.zip(Arrays.stream(x), Arrays.stream(y),
  5. (arg1, arg2) -&gt; { data.put(arg1, arg2); return 0; };
  6. var result = myStream.collect(Collectors.toList()); // ideally don&#39;t want this line

Without the collect( ) line I don't populate the map, so what's simplest way to do this, I tried count() instead of collect but this shortcuts the zip entirely.
Or is there a simpler one line solution without Streams.zip to populate a map from two lists?

答案1

得分: 5

你应该使用 Streams#forEachPair 替代:

  1. String x[] = {"a", "b"};
  2. String y[] = {"c", "d"};
  3. var data = new HashMap<String, String>();
  4. Streams.forEachPair(Arrays.stream(x), Arrays.stream(y), data::put);
  5. System.out.println(data); // {a=c, b=d}

显然,如果你不需要控制 HashMap,你可以直接使用 collect 方法:

  1. String x[] = {"a", "b"};
  2. String y[] = {"c", "d"};
  3. var result = Streams.zip(Arrays.stream(x), Arrays.stream(y), Maps::immutableEntry)
  4. .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
  5. System.out.println(result); // {a=c, b=d}
英文:

You should use Streams#forEachPair instead:

  1. String x[] = {&quot;a&quot;, &quot;b&quot;};
  2. String y[] = {&quot;c&quot;, &quot;d&quot;};
  3. var data = new HashMap&lt;String, String&gt;();
  4. Streams.forEachPair(Arrays.stream(x), Arrays.stream(y), data::put);
  5. System.out.println(data); // {a=c, b=d}

Obviously if you don't need to control HashMap, you can just collect:

  1. String x[] = {&quot;a&quot;, &quot;b&quot;};
  2. String y[] = {&quot;c&quot;, &quot;d&quot;};
  3. var result = Streams.zip(Arrays.stream(x), Arrays.stream(y), Maps::immutableEntry)
  4. .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
  5. System.out.println(result); // {a=c, b=d}

答案2

得分: 0

另一种方法是:

  1. String[] keys = {"k1", "k2"};
  2. String[] values = {"v1", "v2"};
  3. Map<String, String> result = IntStream.range(0, keys.length).boxed()
  4. .collect(Collectors.toMap(i -> keys[i], i -> values[i]));

这种方法的优点是在不必在合并条目之前手动创建映射条目的情况下保持无副作用,所有操作由收集器自身处理。

英文:

Yet another approach:

  1. String[] keys = {&quot;k1&quot;, &quot;k2&quot;};
  2. String[] values = {&quot;v1&quot;, &quot;v2&quot;};
  3. Map&lt;String, String&gt; result = IntStream.range(0, keys.length).boxed()
  4. .collect(Collectors.toMap(i -&gt; keys[i], i -&gt; values[i]));

This has the advantage of being side-effect free while not having to create map entries manually before merging them, all handled by the collector itself.

huangapple
  • 本文由 发表于 2020年10月14日 23:18:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/64356476.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定