英文:
Combining to operations using java streams
问题
我正在执行以下两个操作:
- 遍历对象列表,并根据条件创建一个
String, Boolean
的映射。
Map<String, Boolean> myMap = new HashMap<>();
Iterator<Person> iterator = personList.iterator();
while (iterator.hasNext()) {
Person person = iterator.next();
if (isValidPerson(person)) {
if (person.getName() != null) {
myMap.put(person.getName(), true);
} else {
myMap.put(person.getName(), false);
}
}
}
现在,我正在检查名称列表与上面创建的映射是否匹配,如果值为 true,则添加到最终列表。
List<String> refinedList = new ArrayList<>();
for (String name : nameList) {
if (myMap.get(name) != null && myMap.get(name)) {
refinedList.add(name);
}
}
我需要使用 Java Stream 简化这个逻辑。除此之外,上述代码是正常工作的。
英文:
I'm doing the below two operations
- Iterating through a list of Objects and creating a map of
String, Boolean
based on a condition.
Map<String,Boolean> myMap = new HashMap<>();
Iterator<Person> iterator = personList.iterator();
while (iterator.hasNext()) {
Person person = iterator.next();
if (isValidperson(person)) {
if (person.getName() != null) {
myMap.put(person.getName(), true);
} else {
myMap.put(person.getName(), false);
}
}
}
Now Im checking a list of Names against that map that I created above and if the value is true then adding to a final list
List<String> refinedList = new ArrayList<>();
for (String name : nameList) {
if (myMap.get(name) != null && myMap.get(name)) {
refinedList.add(name);
}
}
I need to simplify the logic using Java streams. The above works fine otherwise.
答案1
得分: 3
在第一步操作中,您正在过滤掉所有无效的人,并将有效的人收集到一个映射中,因此:
Map<String, Boolean> myMap = personList.stream()
.filter(YourClass::isValidPerson)
.collect(Collectors.toMap(x -> x.getName(), x -> x.getName() != null))
但实际上,该映射最多只会有一个false
条目,因为您不能将多个null
添加到HashMap
中,因此使用HashMap
没有太多意义。
我建议使用HashSet
:
Set<String> mySet = personList.stream()
.filter(YourClass::isValidPerson)
.map(Person::getName)
.filter(Objects::nonNull)
.collect(Collectors.toSet())
然后您可以轻松地使用O(1)时间检查contains
:
List<String> refinedList = nameList.stream().filter(mySet::contains).collect(Collectors.toList());
英文:
In the first operation you are filtering out all the non-valid persons, and collecting the valid persons to a map, so:
Map<String,Boolean> myMap = personList.stream()
.filter(YourClass::isValidPerson)
.collect(Collectors.toMap(x -> x.getName(), x -> x.getName() != null))
But really though, the map is going to have at most one false
entry, since you can't add multiple null
s into a HashMap
, so there isn't much point in using a HashMap
at all.
I suggest using a HashSet
:
Set<String> mySet = personList.stream()
.filter(YourClass::isValidPerson)
.map(Person::getName)
.filter(Objects::nonNull)
.collect(Collectors.toSet())
And then you can easily check contains
with O(1) time:
List<String> refinedList = nameList.stream().filter(mySet::contains).collect(Collectors.toList());
答案2
得分: 0
你可以直接通过检查nameList
中的包含关系来筛选列表,并在列表中收集名称。
List<String> refinedList =
personList.stream()
.filter(e -> isValidperson(e))
.map(e -> e.getName())
.filter(Objects::nonNull)
.distinct()
.filter(e -> nameList.contains(e))
.collect(Collectors.toList());
最好从nameList
创建一个集合,以便在O(1)时间复杂度内更快地执行contains()
操作。
Set<String> nameSet = new HashSet<String>(nameList);
注意: 如果nameList
不包含重复项,这将起作用。
英文:
You can directly filter the list by checking contains in nameList
and collect the names in list
List<String> refinedList =
personList.stream()
.filter(e -> isValidperson(e))
.map(e -> e.getName())
.filter(Objects::nonNull)
.distinct()
.filter(e -> nameList.contains(e))
.collect(Collectors.toList());
And it better to create a set from nameList
to make the contains()
operation faster in O(1)
Set<String> nameSet = new HashSet<String>(nameList);
Note: This will works if nameList
doesn't contains duplicate.
答案3
得分: 0
这应该可以工作。
首先,创建一个 People(人员) 的列表。
List<Person> personList = List.of(new Person("Joe"),
new Person(null), new Person("Barb"), new Person("Anne"), new Person("Gary"));
然后是 nameList(名字列表)。注意最好将其放入一个集合中,以便于:
- 避免重复项,
- 使查找过程更高效。
Set<String> nameSet = Set.of("Joe", "Anne", "Ralph");
现在,这个过程通过以下方式工作:
- 对有效和无效的人员进行过滤。
- 将这些人员映射到一个名字。
- 根据是否为 null 进行过滤,然后再检查名字是否在名字集合中。
- 将结果放入一个列表中。
注意:在某些情况下,根据方法类型和调用上下文,lambdas
可能会被 Method References
替代。
List<String> names = personList.stream()
.filter(person -> isValidperson(person))
.map(Person::getName)
.filter(name -> name != null && nameSet.contains(name))
.collect(Collectors.toList());
System.out.println(names);
输出
[Joe, Anne]
因为没有提供条件,所以这是一个虚拟的方法
public static boolean isValidperson(Person person) {
return true;
}
简单的 person 类
class Person {
String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
英文:
This should work.
First, create a list of People.
List<Person> personList = List.of(new Person("Joe"),
new Person(null), new Person("Barb"), new Person("Anne"), new Person("Gary"));
Then the nameList. Note it is best to put this in a set to
- avoid duplicates, and
- make the lookup process more efficient.
Set<String> nameSet = Set.of("Joe", "Anne", "Ralph");
Now this works by
- filtering on a valid vs invalid person.
- mapping those people to a name
- filtering on whether null and then if the name is in the set of names
- and placing in a list.
Note: In some cases, lambdas
could be replaced by Method References
depending on method types and calling contexts.
List<String> names = personList.stream()
.filter(person -> isValidperson(person))
.map(Person::getName)
.filter(name -> name != null && nameSet.contains(name))
.collect(Collectors.toList());
System.out.println(names);
Prints
[Joe, Anne]
Dummy method since criteria not provided
public static boolean isValidperson(Person person) {
return true;
}
Simple person class
class Person {
String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论