Lambda - Java 7 Alternatives

So I have been coding in C# for the past 6 month and I want to go back and finish (update probably a better word) a project that has been in the backburner since November, however I was in the middle of a re-factoring of code so I could introduce new features.

Quite a lot of this code was the UI, I wanted a clean way in triggering events and well, if I Java 7 had delegates or lamdas I could easily pass said function to the UI element in question and have it invoke the method upon press. However, of course you can’t do this in Java 7 or below :(.

What are your handy alternatives to this problem? Anonymous interfaces seem like the only way to sort of do what you require.

Like I could do this:


public interface IEntityAction{

    void execute();

}

Then pass it to a button like so:


Button moveLeft = new Button(position, new IEntityAction{

    public void execute(){
        // Change state here
    }

});

That looks just…horrible.

As you know with C# you could easily just do:


Button moveLeft = new Button(position, player.MoveLeft);

// Then in button
public void OnClick()
{
    action.Invoke();
}

Any ideas? I would be interested to know how you guys deal with this. I never really knew what Lambdas and Delegates were intil I used C#, I am finding it very hard to think of solutions to prevent a huge amount of cross talk between unrelated classes, although it does not matter to have calls to the player instance in the UI, no one likes it :p.

EDIT:

If you are wondering why I am a little anal about the cleanlinesses of the code is due to this project being developed and updated in the long run, I also won’t be the the only person implementing said updates, I might not even be working with the project any more. The last thing I want to do is dump the poor sap with an absolutely horrible source.

There is this project called as RetroLambda, it works by taking the compiled Java 8 bytecode and generating Java 7 bytecode as the output. It supports the lambdas and method references but doesn’t support other features like streams API.

I have never used this before, but there is a tutorial for this project using Android (said it also works on the desktop) here at http://zserge.com/blog/android-lambda.html

As far as Java 7 goes, I’d probably go with something similar to the following:

class MyApp implements ButtonListener
{
	public init()
	{
		moveLeft  = new Button(position, this);
		moveRight = new Button(position, this);
	}

	@Override
	public void onClick(ButtonEvent event)
	{
		if (button is left)
			// Move left
		else if (button is right)
			// Move right
	}
}

This way you won’t have to be setting up events and their actions in the middle of other code, that would be horrible indeed. You don’t necessarily have to implement “ButtonListener”, you can have member variables which do and pass the responsibility down to them if that’s what your application requires. Java 8 would definitely be helpful if you are able to use it.

That. Is. Awesome.

Very clever, I will give it a shot and see if there is any problems. The project is on android so that will be my first test, just to be safe.

On the git page, the author states that if they release a Java 8 version that no longer creates a new class for every dynamic invocation, it could bust the whole thing. That’s a bit of a worry if you are developing for desktop, as most people have Java on auto-update.

The classic solution is to use one-method-classes. Which are often anonymous.

Why can you not use Java 8 and make your life easier? :slight_smile:

Probably should have mentioned in op that the project is on Android, which of course only supports java 6/7.

In that case, i would rather stay with what’s common on the platform and what people are used to use instead of making the project rely on some third party bytecode mangler, that might not even work on future bytecode version for whatever reason. People used the Java 1-7 way of doing these things for many years and nobody died of it.

java is bold. that’s how it is.

other languages are not :wink:

Tons of games have a button that can move a player left or right without the use of lamdas or delegates. From the little that you’ve posted, I don’t see what is being gained by using that sort of implementation. Can you clarify the example some more, say more about what you are trying to do?

I do use the equivalent of lamdas in an “event system” for an audio mixer. This allows me to schedule “AudioCommand” items, such as starting or stopping a synthesizer or changing the volume on a track, at a given frame.

public interface AudioCommand
{
	void run(long currentFrame);
}

The various types of commands extend AudioCommand.

Somewhat simplified:

public class PlayCommand implements AudioCommand
{
	private Note note;

	public PlayCommand(Note note)
	{
		this.note= note;
	}
	
	@Override
	public void run(long currentFrame)
	{
		note.play();
	}
}

There’s a similar construction for note.release(), which is used to end a Note. As I said this is simplified, as there is a specific Synth involved, and a given pitch, volume, pan. This is just for showing the basic idea.

Then, at the given frame the following executes (again, some of the scheduling aspects are not shown, just the basic idea):


    for (AudioCommand ac : audioCommands) ac.run();

It seems to me like the above plan will be pretty straight-forward in terms of intelligibility, going forward. I don’t know if this helps as an example or not. It’s just what I came up with, not knowing any better, and not having Java 8 available, and now, having some ambitions to port the code to Android.