【问题标题】:Nested loop conversion to Java Stream嵌套循环转换为 Java Stream
【发布时间】:2020-07-20 17:05:02
【问题描述】:

我有一个List<Person> 人。我需要迭代一个数字列表并为每个人设置一个自定义数字,例如person.setCustomNumber(),如下所示:

代码如下:

public static void main(String[] args) {

    List<Long> customNumnbers = new ArrayList<>();
    customNumnbers.add(100000l);
    customNumnbers.add(100001l);
    customNumnbers.add(100002l);
    customNumnbers.add(100003l);
    customNumnbers.add(100004l);
    customNumnbers.add(100005l);
    customNumnbers.add(100006l);
    customNumnbers.add(100007l);
    customNumnbers.add(100008l);
    
    List<Person> persons = new ArrayList<>();
    persons.add(new Person("Robert"));
    persons.add(new Person("Jim"));
    persons.add(new Person("Mark"));
    persons.add(new Person("Beto"));
    persons.add(new Person("Reando"));
    
    Map<String, Long> map = new HashMap<>();
    List<Long> possibleNumbers = customNumnbers.subList(0, persons.size());
    int n = 0;
    while(n != possibleNumbers.size()) {    
        for (int j = 0; j < persons.size(); j++) {
            persons.get(j).setCustomNumer(possibleNumbers.get(n));
            map.put(persons.get(j).getName(), persons.get(j).getCustomNumer());
            n++;
        }

    }
    map.entrySet().stream().forEach(System.out::println);
}

class Person {
    private Long id;
    private String name;
    private Long customNumer;
    // relevant constructor, getters and setters
}

我想在 java 流中重写这个逻辑,并为每个 Map&lt;String, Long&gt; 映射返回一个名称和自定义编号的新映射。

【问题讨论】:

  • 您的预期输出应该是什么样的?您对流进行了哪些尝试?
  • @Naman 它我正在尝试从中获取地图 Map,我似乎无法找到方法,如果它是列表中的列表,那么我可以使用 flatMap 但这是两个独立的列表,我需要在第二个循环/流中分配数字。我也使用过 IntStream.range 但我无法从另一个流中访问数字。

标签: java java-stream


【解决方案1】:

您可以循环分配数字:

int assignableCount = Math.min(persons.size(), possibleNumbers.size());
for (int i = 0; i < assignableCount; i++)
    persons.get(i).setCustomNumber(possibleNumbers.get(i));

然后使用流来构建地图:

Map<String, Long> map = persons.stream()
    .collect(Collectors.toMap(Person::getName, Person::getCustomNumber);

【讨论】:

    【解决方案2】:

    整个事情可以使用IntStream.range(int, int)来简化。

    // assure the runtime exception is not thrown due to exceeding any of the lists size
    int n= Math.min(customNumnbers.size(), persons.size());  
    
    Map<String, Long> map = IntStream.range(0, n) // iterate indixes 0..n
        .boxed()                                  // Stream<Integer> rather than IntStream
        .collect(Collectors.toMap(                // collect to a Map<String, Long>
            i -> persons.get(i).getName(),        // .. Person's name as a key from persons
            customNumbers::get));                 // .. the Long as a value from customNumbers
    

    顺便说一句。你在customNumnbers 中有错字,应该是customNumbers - 我在我的解决方案中修复了它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-30
      • 2020-04-05
      • 1970-01-01
      • 2017-08-08
      • 1970-01-01
      • 2016-04-24
      相关资源
      最近更新 更多