Is there a java 8 lambda expression equivalent of the let setting? For instance, how would I write this c# linq expression using Java 8 lambda expressions?
String[] lines = new String[]{"Porky.Pig", "Darth.Vader", "Donald.Duck", "George Lucas"};
(from l in lines
let p = l.IndexOf('.')
where p >= 0
select new
{
FirstName = l.Substring(0, p),
LastName = l.Substring(p + 1)
}).Dump();
I want to evaluate l.IndexOf('.') only once. The closest I came up with is:
String[] lines = new String[]{"Porky.Pig", "Darth.Vader", "Donald.Duck", "George Lucas"};
Arrays.stream(lines)
.filter(x -> x.indexOf('.') > 0)
.map(x -> {
int p = x.indexOf('.');
return new Person (x.substring(0, p), x.substring( p + 1));
});
where:
public class Person {
public Person(String firstName, String lastName)
{
}
}
ok, based on the suggestion in the Shlomi Borovitz's answer I came up with this which makes use of this Pair class
String[] lines = new String[]{"Porky.Pig", "Darth.Vader", "Donald.Duck", "George Lucas"};
Arrays.stream(lines)
.map(x -> Pair.of(x, x.indexOf('.')))
.filter(x -> x.getRight() > 0)
.map(x -> new Person (x.getLeft().substring(0, x.getRight()), x.getLeft().substring( x.getRight() + 1)));
The absence of tuples certainly is a problem. But if we use the declaration of Person
in the question and take up @Ulugbek Umirov's suggestion of using String.split
, this is a reasonably neat solution:
List<Person> persons = Arrays.stream(lines)
.map(s -> s.split("\\."))
.filter(arr -> arr.length > 1)
.map(arr -> new Person(arr[0], arr[1]))
.collect(Collectors.toList());
Not being sure what Dump
does, I've arbitrarily chosen to collect the Person
objects into a List
.
The linq query in C# is converted to "dot syntaxt" (which is regular method calls):
The query:
from l in lines
let p = l.IndexOf('.')
where p >= 0
select new
{
FirstName = l.Substring(0, p),
LastName = l.Substring(p + 1)
}
is converted to something like this:
lines.Select(l => new {l, p = l.IndexOf('.') })
.Where(_ => _.p >= 0)
.Select(_ => new
{
FirstName = _.l.SubString(0, _.p),
LastName = _.l.SubString(_.p + 1)
})
Figure out how to do that in Java.
If there is no equivalent to C#'s anonymous types, tuples are a good idea, where the usage isn't justifying creating another class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With