Title: Java 8+ Unpacking Primitives From Singleton Objects Using Lambda or Stream? Structured Binding in Java?
Tags: java;lambda;java-stream;structured-bindings
Question: Effectively I need to take a subset of data out of a function return, but I don't actually need the returned object. So, is there a way to simply take what I need with a Stream or a Lambda-like syntax? And yes, I understand you CAN use stream().map() to put values into an array, and then decompose the array into named variables, but that's even more verbose for functionally equivalent code.
In C++, this would be called Structured Binding, but I seem to be missing the Java term for it when I search.
Procedural code I seem to be forced to write:
```HandMadeTuple<Integer, Integer, ...&gt; result = methodICurrentlyCall(input);
int thing1 = result.getFirst();
int thing2 = result.getSecond();
...
//thingX's get used for various purposes. Result is never used again.
```
Declarative code I'd like to be able to write:
```int thing1, thing2;
(methodICurrentlyCall(input)) -&gt; (MyType mt) { thing1 = mt.getFirst(); thing2 = mt.getSecond(); };
```
Or
```int thing1, thing2;
Stream.of(methodICurrentlyCall(input)).forEach((mt) -&gt; { thing1 = mt.getFirst(); thing2 = mt.getSecond();} 
```

Comment: If I get your question right, it’s not really about streams, but about [deconstruction](https://cr.openjdk.java.net/~briangoetz/amber/datum.html#records-and-pattern-matching), a language construct currently not supported by Java but planned for the future.

Comment: There’s the fundamental principle that Java does not allow to create references to local variables that could persist longer than the variable itself. You can reference (effectively) final variables because that can be implemented by copying the value, without sacrificing consistency. But you can’t use a lambda expression to assign to local variables of the outer scope. The closest thing you can do, is to use the variables right in the same lambda expression, e.g. `map.for((key,value) -> /*use key and value*/);`. While this example is `void`, similar methods could have a (single) result.

Comment: @AnsarOzden stream().map() doesn't do this either. All it does is output a single value. I could collect the values in a List, but that's worse than useless. I understand "Local variables used in lambda must be final or effectively final," but I have a use case where that constraint is detrimental to producing more succinct, readable code. Is there a bridge, or is this just an unfortunate gap in the Java language?

Comment: @Holger I added some clarification. I believe you're correct that is ONE solution, but I don't necessarily limit the form of the solution to that. Why can't I just give the Complex/Object result of a method call to an in-line function to unpack the Primitives?

Comment: In short - NO, Java doesn't support destructuring yet. But Kotlin (JVM language fully interoperable with Java) does have this feature, so you can rewrite some of your classes in Kotlin and import them in your Java code. But if you plan to use deconstructing across whole application, there is no convenient way of doing it with Java.

Comment: Your approach is discouraged in Java. Local variables used in lambda must be final or effectively final. That means  the variables thing1 and thing2 can't be changed in lambda. It's better to use map feature of streams.

Here is the accepted answer: There's a really awkward hack: arrays.
```final int[] thing1 = {0}, thing2 = {0};
Stream.of(methodICurrentlyCall(input))
  .forEach(mt -&gt; {
    thing1[0] = mt.getFirst();
    thing2[0] = mt.getSecond();
  });
```
The array reference is final, therefore you can use it in lambdas.
I don't recommend this! It is neither shorter nor easier to understand
(Another option is using ```AtomicReference<T&gt;``` or ```AtomicInteger```/```AtomicLong``` instead of the array, but there's a minimal overhead for guaranteeing atomic updates)

If you are looking for pattern matching or destructuring support for Java, this could be implemented in future versions of Java, see this related question on SO: Java object destructuring (even more details at https://cr.openjdk.java.net/~briangoetz/amber/serialization.html)

Comment for this answer: I just wanted to write a similar comment, `var mt = call(); int a = mt.a, b = mt.b;` is the baseline we have the compare with. Is the alternative simpler? Nah. Does it save us from dealing with the object, we're not interested in? Nah, we're now dealing with even more objects, we're actually not interested in.
Comment for this answer: @patrickjp93 then don't use Java for functional programming. I don't go around complaining that Haskell makes side-effectful programming so difficult and "should clean up its act". Different languages were built with different paradigms in mind.
Comment for this answer: I still don't see why `int a,b; do(call()).extract(result -> { a=result.a; b=result.b; })` would be more desirable than `var result=call(); int a=result.a, b=result.b;` – the latter being shorter to write and easier to understand; the former being convoluted and inherently side-effectful with temporary dependencies (you cannot know when the lambda body will be executed, maybe it is only evaluated lazily?)
Comment for this answer: "with a _temporal_ dependency" (not temporary) is what I meant in my previous comment :)
Comment for this answer: While the AtomicInteger answer ANNOYS me, it's tolerable. I can write in a comment to the tune of "Deficiency in Java requiring functional programming quality to lambdas, normal primitives not allowed (as of J8)."

If anyone from Oracle, or another influencer in the Java world sees this, fix your language and let people write reasonable code, for God's sake.


{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 6, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2021:00:03/25/21', 'FavoriteCount': 1.0, 'PostTypeId': 1, 'Tags': '<java><lambda><java-stream><structured-bindings>', 'Title': 'Java 8+ Unpacking Primitives From Singleton Objects Using Lambda or Stream? Structured Binding in Java?', 'ViewCount': 457, 'id': 66805710, 'user_AboutMe': '', 'user_AccountId': 9222511.0, 'user_DisplayName': 'patrickjp93', 'user_Reputation': 379.0, 'user_Views': 196.0, 'user_id': 6851375.0}}