使用Java流合并两个操作

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

Combining to operations using java streams

问题

我正在执行以下两个操作:

  1. 遍历对象列表,并根据条件创建一个 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

  1. Iterating through a list of Objects and creating a map of String, Boolean based on a condition.
		Map&lt;String,Boolean&gt; myMap = new HashMap&lt;&gt;();
		Iterator&lt;Person&gt; 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&lt;String&gt; refinedList = new ArrayList&lt;&gt;();
			for (String name : nameList) {
				if (myMap.get(name) != null &amp;&amp; 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&lt;String,Boolean&gt; myMap = personList.stream()
    .filter(YourClass::isValidPerson)
    .collect(Collectors.toMap(x -&gt; x.getName(), x -&gt; x.getName() != null))

But really though, the map is going to have at most one false entry, since you can't add multiple nulls into a HashMap, so there isn't much point in using a HashMap at all.

I suggest using a HashSet:

Set&lt;String&gt; 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&lt;String&gt; 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&lt;String&gt; refinedList = 
    personList.stream()
              .filter(e -&gt; isValidperson(e))
              .map(e -&gt; e.getName())
              .filter(Objects::nonNull)
              .distinct()
              .filter(e -&gt; 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&lt;String&gt; nameSet = new HashSet&lt;String&gt;(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(名字列表)。注意最好将其放入一个集合中,以便于:

  1. 避免重复项,
  2. 使查找过程更高效。
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&lt;Person&gt; personList = List.of(new Person(&quot;Joe&quot;),
		new Person(null), new Person(&quot;Barb&quot;), new Person(&quot;Anne&quot;), new Person(&quot;Gary&quot;));

Then the nameList. Note it is best to put this in a set to

  1. avoid duplicates, and
  2. make the lookup process more efficient.
Set&lt;String&gt; nameSet = Set.of(&quot;Joe&quot;, &quot;Anne&quot;, &quot;Ralph&quot;);

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&lt;String&gt; names = personList.stream()
		.filter(person -&gt; isValidperson(person))
		.map(Person::getName)
		.filter(name -&gt; name != null &amp;&amp; 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>



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

发表评论

匿名网友

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

确定