Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LambdaJ forEach set

I want to set value to a field of an object so that it will first get the previous value of that field and append something to it and the set it to that field.

In LambdaJ forEach we can do something like this:

forEach(myCollection).setFieldValue("someValue");

But what I need is:

forEach(myCollection).setFieldValue(getFieldValue() + "someValue");

Is it possible in LambdaJ?

like image 829
Tapas Bose Avatar asked Nov 01 '13 07:11

Tapas Bose


2 Answers

I know you asked about LambdaJ, I was curious to do that since it is a common problem.

I was surprised of the result I got doing:

forEach(list).setName(on(User.class).getName() + "someValue");

I though it would be the answer to your question.

So, I tried a different approach by using Guava functional way. It can work for you so I'll post the answer (but I can delete it if you don't agree with it):

Guava functional approach:

    @Test
    public void test_applyPreviousValue() {

         List<User> filteredList = Lists.newArrayList(new User("Fede", 20), new User("Peter", 12), new User("John", 41));

         Function<User, User> getType = new Function<User, User>() {
             public User apply(User input) {
                  input.setName(input.getName()+"someValue");
                  return input;
             }
         };

         Collection<User> result = Collections2.transform(filteredList, getType);
         System.out.println(result);
     }

Hope to help

like image 50
Federico Piazza Avatar answered Sep 22 '22 11:09

Federico Piazza


I had a similar usecase and realized forEach won't help the way I used it.

So I thought closures are a solution:

@Test
public void test() {
    Closure modify = closure();{
        of(Point.class).setLocation(var(Point.class).x+10, 10);          
    }

    List<Point> points = new ArrayList<>();
    points.add(new Point(10, 0));
    points.add(new Point(10, 10));

    modify.each(points);

    for (Point point : points) {
        assertEquals(20, point.getX(), 0.0);
    }
}

But the asserts fails since the object in the collection is not been modified. Maybe I'm doing something wrong there.

In the end I used closures from the apache commons collection.

UPDATE

I was able to solve the puzzle with a closure. Looks like you can't use the free variable direct. Here is the working code:

@Test
public void test() {
    Closure modify = closure();{
        of(this).visit(var(Point.class));
    }

    List<Point> points = new ArrayList<Point>();
    points.add(new Point(10, 0));
    points.add(new Point(10, 10));

    modify.each(points);

    for (Point point : points) {
        assertEquals(20, point.getX(), 0.0);
    }
}

void visit(Point p) {
    p.setLocation(p.x + 10, p.y);
}

Note: instead of this you can also write a class which contains the visit method and use it in the definition of the closure.

like image 30
Spindizzy Avatar answered Sep 19 '22 11:09

Spindizzy