Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elegant way of doing ruby inject in Java 8

Tags:

java

loops

java-8

String result = "";
for(String str : strings) {
    result = apply(result, str);
}
return result;

I want to pass through the result of one operation with next element in the loop. Is there any elegant way of doing this in Java 8?

For example, in Ruby, we can use inject.

strings.inject("") { |s1, s2| apply(s1,s2) }
like image 806
Manikandan Avatar asked Dec 08 '15 18:12

Manikandan


2 Answers

You can use reduce :

String result = strings.stream().reduce("", this::apply);
like image 187
Mrinal Avatar answered Oct 23 '22 06:10

Mrinal


If you don't mind adding a third-party library, you could use Eclipse Collections which has injectInto methods on its object and primitive containers. Eclipse Collections was inspired by the Smalltalk Collections API which also inspired Ruby. Here are some examples of using object (mutable and immutable) and primitive (mutable and immutable) containers with injectInto.

@Test
public void inject()
{
    MutableList<String> strings1 = Lists.mutable.with("1", "2", "3");
    Assert.assertEquals("123", strings1.injectInto("", this::apply));

    ImmutableList<String> strings2 = Lists.immutable.with("1", "2", "3");
    Assert.assertEquals("123", strings2.injectInto("", this::apply));

    IntList ints = IntLists.mutable.with(1, 2, 3);
    Assert.assertEquals("123", ints.injectInto("", this::applyInt));

    LazyIterable<Integer> boxedInterval = Interval.oneTo(3);
    Assert.assertEquals("123", boxedInterval.injectInto("", this::applyInt));

    IntList primitiveInterval = IntInterval.oneTo(3);
    Assert.assertEquals("123", primitiveInterval.injectInto("", this::applyInt));
}

public String apply(String result, String each)
{
    return result + each;
}

public String applyInt(String result, int each)
{
    return result + each;
}

Note: I am a committer for Eclipse Collections

like image 1
Donald Raab Avatar answered Oct 23 '22 05:10

Donald Raab