Still learning Java8. I have code that looks like:
List<String> list = userData.getEmails().stream()
.map(email -> codeThatGetsTheHost(email))
.peek((email, host) -> {//Only print if email is not null
System.out.println("email=" email " host=" host);})
.collect(Collectors.toList()); //should collect hosts.
The above code does not work because the peek() does not have access to the main stream variable, that is email used in map(). How do i fix this?
CodePudding user response:
Either put peek
before the map
to access all the data you need:
List<String> list = userData.getEmails().stream()
.peek(email -> System.out.println("email=" email " host=" email.getHost()))
.map(email -> email.getHost())
.collect(Collectors.toList());
Or perform both actions (completely legal) in the map
method to avoid repeating the getter call:
List<String> list = userData.getEmails().stream()
.map(email -> {
String host = email.getHost();
System.out.println("email=" email " host=" host));
return host;
})
.collect(Collectors.toList());
CodePudding user response:
You should use peek before mapping emails to their hosts. This is a sample code for your case:
import java.util.*;
import java.util.stream.Collectors;
class Email{
public String email;
private String host;
public Email(String email, String host){
this.email = email;
this.host = host;
}
public String getHost(){
return host;
}
}
class UserData{
List<Email> emails = new LinkedList<>();
public List<Email> getEmails(){
return emails;
}
}
public class MyClass {
public static void main(String args[]) {
UserData userData = new UserData();
userData.emails.add(new Email("[email protected]", "host1"));
userData.emails.add(new Email("[email protected]", "host2"));
userData.emails.add(new Email("[email protected]", "host3"));
List<String> list = userData.getEmails().stream()
.peek(email -> System.out.println("email=" email " host=" email.getHost()))
.map(email -> email.getHost())
.collect(Collectors.toList());
System.out.println(list);
}
}
email=Email@7bfcd12c host=host1
email=Email@1c2c22f3 host=host2
email=Email@18e8568 host=host3
[host1, host2, host3]
CodePudding user response:
Keep a Stream<Email>
until you don't need them.
.peek(email -> System.out.println("email=" email " host=" email.getHost()))
.map(Email::getHost)
If host calculation is somewhat expensive, you could make a Stream<Map.Entry<Email, String>>
and have them both in the downstream.
userData.getEmails()
.stream()
.filter(Objects::nonNull)
.map(email -> new AbstractMap.SimpleEntry<>(email, codeThatGetsTheHost(email)))
.peek(entry -> System.out.println("email=" entry.getKey() " host=" entry.getValue()))
.map(Map.Entry::getValue)
.collect(Collectors.toList());