将一系列的对象转换成一个Map。

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

Convert a stream of Objects to a Map

问题

以下是您要翻译的内容:

我想要将一系列的对象转换为一个映射。键是对象本身,值是 Function.identity()。我的目标是为每个人创建一个增量索引。

public class Person {
  private String firstName;
  private String lastName;
}

/* 期望的结果
  键:[Person1], 值:1  
  键:[Person2], 值:2  
  键:[Person3], 值:3
*/
public Map<Person, Integer> getMapOfPersons(Stream<Person> persons) {
  return persons.filter(p -> "John".equalsIgnoreCase(p.getFirstName()))
    .collect(Collectors.toMap(Function.identity(), person -> 1));
}

我的问题是,在应用 .filter() 后,我无法将对象作为键(甚至值)放入 .toMap() 方法中。

英文:

I would like to convert a stream of Objects to a Map. The key is the object itself and the value is Function.identity(). My goal is to create an incremental index for every Person.

public class Person {
  private String firstName;
  private String lastName;
}

/* Expected Result
  Key:[Person1], value:1  
  Key:[Person2], value:2  
  Key:[Person3], value:3
*/
public Map&lt;Person, Integer&gt; getMapOfPersons(Stream&lt;Person&gt; persons) {
  return persons.filter(p -&gt; &quot;John&quot;.equalIgnoreCase(p.getFirstName)
  .collect(Collectors.toMap(Person, Function.identity()));
}

My problem is that after applying the .filter(), I can't put my object as a key (or even value) in .toMap() method.

答案1

得分: 2

你可以分两步完成:

public Map<Person, Integer> getMapOfPersons(Stream<Person> persons) {
  List<Person> filtered = persons.filter(p -> "John".equalsIgnoreCase(p.getFirstName))
                                 .collect(Collectors.toList());
  return IntStream.range(0, filtered.size())
                  .boxed()
                  .collect(Collectors.toMap(filtered::get, i -> i + 1));
}
英文:

You could make it in two steps:

public Map&lt;Person, Integer&gt; getMapOfPersons(Stream&lt;Person&gt; persons) {
  List&lt;Person&gt; filterd = persons.filter(p -&gt; &quot;John&quot;.equalIgnoreCase(p.getFirstName))
                                 .collect(Collectors.toList());
  return IntStream.range(0, filterd.size())
                  .boxed()
                  .collect(Collectors.toMap(filterd::get, i -&gt; i + 1));
}

答案2

得分: 0

你可以尝试类似这样的代码:

public Map<Person, Integer> getMapOfPersons(Stream<Person> persons) {
  AtomicInteger counter = new AtomicInteger(0);
  return persons.filter(p -> "John".equalsIgnoreCase(p.getFirstName()))
                .collect(Collectors.toMap(p -> p, p -> counter.getAndIncrement()));
}
英文:

You can try something like this:

public Map&lt;Person, Integer&gt; getMapOfPersons(Stream&lt;Person&gt; persons) {
  AtomicInteger counter = new AtomicInteger(0);
  return persons.filter(p -&gt; &quot;John&quot;.equalIgnoreCase(p.getFirstName())
  .collectors.toMap(p-&gt;p, counter.getAndIncrement());
}

答案3

得分: 0

你可以使用 AtomicInteger 来生成一个递增值作为 Map 的值:

public Map<Person, Integer> getMapOfPersons(Stream<Person> persons) {
  final AtomicInteger atomicInteger = new AtomicInteger();
  return persons
      .filter(p -> "John".equalsIgnoreCase(p.getFirstName()))
      .collect(Collectors.toMap(Function.identity(), notUsed -> atomicInteger.incrementAndGet()));
}

注意在使用并行流时要小心,因为它依赖于处理的顺序。但是它会产生唯一的值,因为 AtomicInteger 是线程安全的。

英文:

You could use AtomicInteger to generate an increasing value as value to your Map:

public Map&lt;Person, Integer&gt; getMapOfPersons(Stream&lt;Person&gt; persons) {
  final AtomicInteger atomicInteger = new AtomicInteger();
  return persons
      .filter(p -&gt; &quot;John&quot;.equalsIgnoreCase(p.getFirstName()))
      .collect(Collectors.toMap(Function.identity(), notUsed -&gt; atomicInteger.incrementAndGet()));
}

Beware of using this with parallel streams since it relies on the order of the processing. It will, however, render unique values since AtomicInteger is thread safe.

huangapple
  • 本文由 发表于 2020年10月6日 22:38:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/64228070.html
匿名

发表评论

匿名网友

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

确定