Richard Marriott
Richard Marriott

Reputation: 113

Do Java 8 Streams support any form of range variable?

In C#, using Linq, I can define a range variable (length in this case) to be used within the expression, e.g:

var result = from name in names
             let length = name.Length //assume this is expensive so we don't want to compute it twice
             select new MyClass(length * length, length)

Is there a way of defining a similar range variable (i.e. such as length in the above example) in Java 8?

Upvotes: 0

Views: 138

Answers (3)

Dennis_E
Dennis_E

Reputation: 8894

A- Java does not know sql-syntax so no let keyword.

B- The let keyword turns into a select of an anonymous type. Java also does not know anonymous types.

I think the following is somewhat similar to what LINQ creates behind the scenes:

private class TransparentIdentifier
{
    String value;
    int length;

    public TransparentIdentifier(String s) {
        this.value = value;
        length = value.length();
    }

    public int getLength() { return length; }
    public String getValue() { return value; }

}

names.stream()
   .map(name -> new TransparentIdentifier(name))
   .map(ti => new MyClass(ti.getLength() * ti.getLength(), ti.getLength()));

Upvotes: 1

Pshemo
Pshemo

Reputation: 124275

I am not sure if that is what you are looking for, but how about something like this

List<MyClass> result = names.stream()
                            .map(name->name.length)
                            .map(length->new MyClass(length*length, length))
                            .collect(Collectors.toList());

Upvotes: 3

dkatzel
dkatzel

Reputation: 31648

Why not

List<MyClass> list = new ArrayList<>();
names.forEach(name ->{
        int length = name.length();
        list.add(new MyClass(length*length, length));
    });

You can probably turn this into a custom Collector as well.

EDIT changed Collection of MyClasses from Set to List since to support be duplicate lengths

Upvotes: 1

Related Questions