Sti*_*ode 3 java java-8 java-stream
假设我有这两个列表
List<Person> persons = Arrays.asList(
new Person(1, "Mike", "Canada"),
new Person(2, "Jill", "England"),
new Person(3, "Will", "Whales"),
new Person(4, "Mary", "Spain"));
List<Metadata> metadata= Arrays.asList(
new metadata(1, "2000-01-01", "Naturalized", "Bachelor's of Arts"),
new metadata(2, "2001-01-01", "ExPat", "Masters of Chemestry"),
new metadata(3, "2017-05-01", "Citizen", "Buiness Management"),
new metadata(4, "2018-04-16", "Work Visa", "Nursing"));
Run Code Online (Sandbox Code Playgroud)
最终结果是新列表:
List<PersonWithMetadata> personsAndMEtadata = Arrays.asList(
new PersonWithMetadata(1, "Mike", "Canada", "2000-01-01", "Naturalized", "Bachelor's of Arts"),
new PersonWithMetadata(2, "Jill", "England", "2001-01-01", "ExPat", "Masters of Chemestry"),
new PersonWithMetadata(3, "Will", "Whales", "2017-05-01", "Citizen", "Buiness Management"),
new PersonWithMetadata(4, "Mary", "Spain", "2018-04-16", "Work Visa", "Nursing"));
Run Code Online (Sandbox Code Playgroud)
我试图找到一种Java流方式将前两个列表组合成第三个 - 就像第一个输入上的SQL连接是一个id号.似乎应该有办法做到这一点,但我不知所措.怎么做的?另外,假设两个输入列表之间至多有一个匹配.
YCF_L的解决方案应该可行,但它是一个O(n 2)解决方案.通过将一个列表转换为从id到对象的映射,然后迭代到另一个并从地图获取匹配值,可以实现O(n)解决方案:
Map<Integer, Person> personMap =
persons.stream().collect(Collectors.toMap(Person::getId, Function.identity());
List<PersonWithMetadata> result =
metadata.stream()
.map(m -> new PersonWithMetadata(personMap.get(m.getId()), m)
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
在示例数据中,列表具有匹配顺序的匹配对象.如果这个假设对于真正的问题也是如此,那么解决方案可能必须更容易 - 您可以流式传输索引并从列表中获取相应的值:
List<PersonWithMetadata> result =
IntStream.reange(0, persons.size())
.map(i -> new PersonWithMetadata(persons.get(i), metadata.get(i))
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)