有没有方法在Java 8的流内部设置函数的局部变量

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

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 = &quot;&quot;;
List&lt;String&gt; deliveryAddresses = 
            compositeEvent.getData().getShopperProfiles().getDeliveryAddressIDs();
List&lt;Addresses&gt; addresses = 
            compositeEvent.getData().getPersons().getContactInfo().getAddresses();
for(String deliveryAddress : deliveryAddresses){
    for(Addresses address : addresses) {
        if(deliveryAddress.equalsIgnoreCase(address.getId())){
            if(address.getModified().compareTo(latestDeliveryAddress)&gt;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&lt;String&gt; stringStream = deliveryAddresses.stream().filter({
                    deliveryAddress -&gt; addresses.stream().anyMatch(address -&gt; address.getId().equalsIgnoreCase(deliveryAddress))

I am now trying to do this

 Map&lt;String,String&gt; dates =
                    deliveryAddresses.stream()
                            .filter (
                                    deliveryAddress -&gt; addresses.stream()
                                            .allMatch(address -&gt; 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 = {&quot;&quot;};  
deliveryAddresses.stream().forEach (
                                        deliveryAddress -&gt; addresses.stream().forEach(addresses1 -&gt; 
                                        {
                                            if(addresses1.getId().equals(deliveryAddress)){
                                                if(addresses1.getModified().compareTo(deliveryAddress)&lt;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&lt;String&gt; deliveryAddresses =
    compositeEvent.getData().getShopperProfiles().getDeliveryAddressIDs();
List&lt;Addresses&gt; addresses =
    compositeEvent.getData().getPersons().getContactInfo().getAddresses();

String latestDeliveryAddress = addresses.stream()
    .filter(a -&gt; deliveryAddresses.contains(a.getId()))
    .max(Comparator.comparing(Addresses::getModified))
    .map(Addresses::getId)
    .orElseThrow(() -&gt; new IllegalStateException(&quot;no matching address&quot;));

If you truly want to match IDs case insensitive, you may use

Set&lt;String&gt; deliveryAddresses = new TreeSet&lt;&gt;(String.CASE_INSENSITIVE_ORDER);
deliveryAddresses.addAll(
    compositeEvent.getData().getShopperProfiles().getDeliveryAddressIDs());
List&lt;Addresses&gt; addresses =
    compositeEvent.getData().getPersons().getContactInfo().getAddresses();

String latestDeliveryAddress = addresses.stream()
    .filter(a -&gt; deliveryAddresses.contains(a.getId()))
    .max(Comparator.comparing(Addresses::getModified))
    .map(Addresses::getId)
    .orElseThrow(() -&gt; new IllegalStateException(&quot;no matching address&quot;));

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&lt;String&gt; elements = List.of(&quot;Fire&quot;, &quot;Wind&quot;, &quot;Rain&quot;);
	elements.stream().anyMatch(element -&gt; {
		variable = element; 
        return element.startsWith(&quot;Ra&quot;);	
	});
}

huangapple
  • 本文由 发表于 2020年10月15日 00:08:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/64357360.html
匿名

发表评论

匿名网友

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

确定