英文:
Are there ways set a local variable of a function inside stream java 8
问题
String latestDeliveryAddress = "";
List<String> deliveryAddresses =
compositeEvent.getData().getShopperProfiles().getDeliveryAddressIDs();
List<Addresses> addresses =
compositeEvent.getData().getPersons().getContactInfo().getAddresses();
for (String deliveryAddress : deliveryAddresses) {
for (Addresses address : addresses) {
if (deliveryAddress.equalsIgnoreCase(address.getId())) {
if (address.getModified().compareTo(latestDeliveryAddress) > 0) {
latestDeliveryAddress = deliveryAddress;
}
}
}
}
Stream<String> stringStream = deliveryAddresses.stream().filter(
deliveryAddress -> addresses.stream().anyMatch(address -> address.getId().equalsIgnoreCase(deliveryAddress))
);
Map<String, String> dates = deliveryAddresses.stream()
.filter(deliveryAddress -> addresses.stream()
.anyMatch(address -> address.getId().equals(deliveryAddress)))
.collect(Collectors.toMap(addresses.get(0).getId(), addresses.get(0).getModified()));
final String[] latestDeliveryAddress = {""};
deliveryAddresses.stream().forEach(deliveryAddress ->
addresses.stream().forEach(address -> {
if (address.getId().equals(deliveryAddress)) {
if (address.getModified().compareTo(latestDeliveryAddress[0]) < 0) {
latestDeliveryAddress[0] = address.getId();
}
}
})
);
英文:
I am new to java 8 and exploring different possibilities with it .I have a block of code that looks like this
String latestDeliveryAddress = "";
List<String> deliveryAddresses =
compositeEvent.getData().getShopperProfiles().getDeliveryAddressIDs();
List<Addresses> addresses =
compositeEvent.getData().getPersons().getContactInfo().getAddresses();
for(String deliveryAddress : deliveryAddresses){
for(Addresses address : addresses) {
if(deliveryAddress.equalsIgnoreCase(address.getId())){
if(address.getModified().compareTo(latestDeliveryAddress)>0){
latestDeliveryAddress = deliveryAddress;
}
}
}
}
I want to know if its even possible to do this using java stream and lambda expressions?
I can get to point where I can find the address but can't find a way to set local variable with it
Stream<String> stringStream = deliveryAddresses.stream().filter({
deliveryAddress -> addresses.stream().anyMatch(address -> address.getId().equalsIgnoreCase(deliveryAddress))
I am now trying to do this
Map<String,String> dates =
deliveryAddresses.stream()
.filter (
deliveryAddress -> addresses.stream()
.allMatch(address -> address.getId().equals(deliveryAddress)))
.collect(Collectors.toMap(addresses.get(0).getId(),addresses.get(0).getModified()));
but to Map method is throwing an error .
My final solution is this. It works but please let me know if there is a better way to do this
final String[] latestDeliveryAddress = {""};
deliveryAddresses.stream().forEach (
deliveryAddress -> addresses.stream().forEach(addresses1 ->
{
if(addresses1.getId().equals(deliveryAddress)){
if(addresses1.getModified().compareTo(deliveryAddress)<0){
latestDeliveryAddress[0] = addresses1.getId();
}
}
})
);
答案1
得分: 2
通常建议学习[流 API]及其所有操作。forEach
应该是最后的选择,或者,如果您尝试重写循环解决方案,并且只发现 forEach
合适,这可能是一个信号,最好还是保持循环。
您可以使用
List<String> deliveryAddresses =
compositeEvent.getData().getShopperProfiles().getDeliveryAddressIDs();
List<Addresses> addresses =
compositeEvent.getData().getPersons().getContactInfo().getAddresses();
String latestDeliveryAddress = addresses.stream()
.filter(a -> deliveryAddresses.contains(a.getId()))
.max(Comparator.comparing(Addresses::getModified))
.map(Addresses::getId)
.orElseThrow(() -> new IllegalStateException("no matching address"));
如果您真的想要进行不区分大小写的 ID 匹配,可以使用
Set<String> deliveryAddresses = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
deliveryAddresses.addAll(
compositeEvent.getData().getShopperProfiles().getDeliveryAddressIDs());
List<Addresses> addresses =
compositeEvent.getData().getPersons().getContactInfo().getAddresses();
String latestDeliveryAddress = addresses.stream()
.filter(a -> deliveryAddresses.contains(a.getId()))
.max(Comparator.comparing(Addresses::getModified))
.map(Addresses::getId)
.orElseThrow(() -> new IllegalStateException("no matching address"));
一般而言,如果大小可能会变大,建议对 deliveryAddresses
使用 Set
。对于区分大小写的匹配,您可以使用 HashSet
,它会提供更快的查找速度。
不过,奇怪的是您必须在此处执行两个集合的匹配操作。无论 compositeEvent.getData()
返回什么,都应该提供一个 API,以便首先只获取适用的地址。
[流 API]:https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#method.summary
英文:
It’s generally recommend to study the Stream API and all of its operations. forEach
should be the last resort or, well, if you try to rewrite a loop solution and only find forEach
suitable, it may be a sign that it’s better to stay with the loop.
You can use
List<String> deliveryAddresses =
compositeEvent.getData().getShopperProfiles().getDeliveryAddressIDs();
List<Addresses> addresses =
compositeEvent.getData().getPersons().getContactInfo().getAddresses();
String latestDeliveryAddress = addresses.stream()
.filter(a -> deliveryAddresses.contains(a.getId()))
.max(Comparator.comparing(Addresses::getModified))
.map(Addresses::getId)
.orElseThrow(() -> new IllegalStateException("no matching address"));
If you truly want to match IDs case insensitive, you may use
Set<String> deliveryAddresses = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
deliveryAddresses.addAll(
compositeEvent.getData().getShopperProfiles().getDeliveryAddressIDs());
List<Addresses> addresses =
compositeEvent.getData().getPersons().getContactInfo().getAddresses();
String latestDeliveryAddress = addresses.stream()
.filter(a -> deliveryAddresses.contains(a.getId()))
.max(Comparator.comparing(Addresses::getModified))
.map(Addresses::getId)
.orElseThrow(() -> new IllegalStateException("no matching address"));
Generally, it’s recommended to use a Set
for deliveryAddresses
if the size can get large. For case sensitive matches, you can use a HashSet
, which will provide an even faster lookup.
Though, it’s strange that you have to perform such match operation of two collections at this place. Whatever compositeEvent.getData()
returns, should provide an API to get only the applicable addresses in the first place.
答案2
得分: 0
你可以这样做,但我正在使用类属性而不是方法内的局部变量:
private String variable;
void testStream() {
List<String> elements = List.of("Fire", "Wind", "Rain");
elements.stream().anyMatch(element -> {
variable = element;
return element.startsWith("Ra");
});
}
英文:
You can do it like this, however I am using a class attribute instead of a local variable inside a method:
private String variable;
void testStream() {
List<String> elements = List.of("Fire", "Wind", "Rain");
elements.stream().anyMatch(element -> {
variable = element;
return element.startsWith("Ra");
});
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论