Jump to content
Can't remember your login details? Read more... ×
Sign in to follow this  
syntaxerror

Storing Key and Method in List? (Java)

Recommended Posts

So, here's what I want. I have a set of keys, A B C D, each corresponds to a certain method, MA MB MC MD. I need to be able to store them in a list so that when a user enters a command ("BCDDBA") it goes through the list, finds the keys and executes the corresponding function.

 

Is this even possible? I vaguely recall HashMaps, but I've no idea if this is possible.

 

Thanks in advance guys.

Share this post


Link to post
Share on other sites

So, here's what I want. I have a set of keys, A B C D, each corresponds to a certain method, MA MB MC MD. I need to be able to store them in a list so that when a user enters a command ("BCDDBA") it goes through the list, finds the keys and executes the corresponding function.

 

Is this even possible? I vaguely recall HashMaps, but I've no idea if this is possible.

 

Thanks in advance guys.

Hey mate a couple of solutions come to mind.

One is a map between string -> command class

 

So you have a Command Class which is abstract with a function called "run()". Then you have 4 sub-classes named MA, MB etc. Each implementing run in the right way. Your code then becomes

 

List<String, Command> theList

foreach( char c in string "ABCDAA")

theList[c].second.run();

 

Let me know if you need more info and I can describe it better

Share this post


Link to post
Share on other sites

What you want to do is definitely possible, and there are a few ways to do it.

 

One is using anonymous functions and a hash map. For example:

 

interface Foo
{
	public void run();
}

Then you can write something like:

HashMap<String, Foo> dispatcher = new HashMap();
dispatcher.put
(
	"A", 
	new Foo()
	{
		public void run()
		{
			MA();
		}
	 }
);
And so forth.

 

Calling it should be as simple as going

dispatcher.get().run()

This has the advantage that it keeps declaration and usage together, otherwise you need to define a new class somewhere else, and then add it to the table. It also makes it obvious how and where new key:method pairs should be added.

 

An alternative is to just have a bunch of objects in a list with a key string. Then you just iterate over the list looking for an object whose key string matches the key, then you call its run method. This will be fine for small number of objects, but does not scale well. This can be somewhat alleviated by keeping the list sorted so you can always do a binary search.

Share this post


Link to post
Share on other sites

same solution really, main difference is I don't like anonymous classes. There is one other method which I am not as big a fan of which is

you create a function

void f(Char c)
{
		   if(c=='A') a();
		   else if(c=='B') b();
		   //etc... or you could do a swtich case thing but again personal preference I don't like switches....LOL

}

Share this post


Link to post
Share on other sites

As PP said, what we commons call the Command Pattern.

 

Combine with a Factory Pattern, and you're in business

 

 

// This is a singleton class (probably need different syntax here for Java...)
public static class MethodFactory()
{
	private static HashMap<string,IMethod> methLookup;

	static MethodFactory()
	{
		// freespace's hashmap method
		methLookup = new HashMap<string,IMethod>();
		methLookup.Add("A", new MethodA());
		methLookup.Add("B", new MethodB());
		methLookup.Add("C", new MethodC());
		// and so on
	}	

	public static IMethod CreateInstanceIfstatements(string command)
	{
		IMethod meth = null;
		if (command == "A")
			meth = new MethodA();
		else if (command == "B")
			meth = new MethodB();
		else if	(command == "C")
			meth = new MethodC();
			// and so on.

		return meth;						
	}

	public static IMethod CreateInstanceHashMap(string command)
	{
		return methLookup[command];
	}
}

public interface IMethod
{
	void Run();
}

public class MethodA : IMethod
{
	public MethodA()
	{
		// constructor particular for A here.  
		// the constructor might have parameters to initialize Run()
	}

	public void Run()
	{
		// Do the actions particular to A here.
	}
}

public class MethodB : IMethod
{
	public MethodB()
	{
		// constructor particular for A here.  
		// the constructor might have parameters to initialize Run()
	}

	public void Run()
	{
		// Do the actions particular to A here.
	}
}

public class MethodC : IMethod
{
	public MethodC()
	{
		// constructor particular for A here.  
		// the constructor might have parameters to initialize Run()
	}

	public void Run()
	{
		// Do the actions particular to A here.
	}
}

// the application entry point
public static int main(string[] args)
{
	// get the command here. lets assume one command per arg
	for (int i = 0; i < args.Length; i++)
	{
		IMethod meth = MethodFactory.CreateInstance(args[i])
		meth.Run();
	}
}

That's the traditional way. C# for example has delegates (similar to function pointers), lambda expressions, and expression trees, which change the implementation signficantly, and also cater for more complex issues, like if you wanted different method calls to have different number and types of parameters.

Share this post


Link to post
Share on other sites

Im sorry kikz, but freespace's solution seems way less maintainance then yours, especially in java where every class has to be defined in its own file.

You'll just end up with a total mess of tiny class files, and the functions' implementations will be totally divorced from where you are calling them, making it non-obvious whats going on. Consider how hard it is to add another function in your version(new class, class file, modify if statement tree) vs freespaces.

I just feel in this case (which is screaming for first class function support in java), you want to be able to see, in one place, what function is associated to what key - and freespace's does that nicely.

 

Another option is of course reflection. ill see if i can make up an example.

Share this post


Link to post
Share on other sites

Im sorry kikz, but freespace's solution seems way less maintainance then yours, especially in java where every class has to be defined in its own file.

You'll just end up with a total mess of tiny class files, and the functions' implementations will be totally divorced from where you are calling them, making it non-obvious whats going on. Consider how hard it is to add another function in your version(new class, class file, modify if statement tree) vs freespaces.

I just feel in this case (which is screaming for first class function support in java), you want to be able to see, in one place, what function is associated to what key - and freespace's does that nicely.

 

Another option is of course reflection. ill see if i can make up an example.

 

Don't be sorry :p

 

In Freespaces method, you still need to define each of the methods, MA, MB etc. The only extra weight of the command pattern is implenting an interface. Lets say all MA() does is System.out.writeline("hello world");

 

freespace's looks like

new Foo()
{
	public void run()
	{
		MA();
	}
}

// Where is MA defined?
static void MA()
{
  System.out.writeline("hello world");
}

Using a command pattern (the interface need only be defined once):

interface IMethod
{
	void Run()
}

class MA : IMethod
{
	public void Run()
	{
		system.out.writeline("hello world");		  
	}
}
Hardly a complete mess. I accept those class files might be annoying. Not something I considered from over here in c# land :)

Adding a new command in freespaces still requires creating the method somewhere, MX()? and then adding to the HashMap.

 

 

 

That's the traditional way. C# for example has delegates (similar to function pointers), lambda expressions, and expression trees, which change the implementation signficantly, and also cater for more complex issues, like if you wanted different method calls to have different number and types of parameters.

I did say Traditional :) There's plenty of new language constructs to use instead of a command pattern. In c#, nowadays you can use anonymous methods in much the same way as what freespace has shown.

class Program
{
	private delegate void Method();

	static void Main(string[] args)
	{			
		IDictionary<string, Method> methods = new Dictionary<string, Method>();

		methods.Add("A", delegate { Console.WriteLine("Hello World"); });
			
		methods["A"]();
	}
}

Both ways will work. Pretty much comes down to personal preference. I don't think the maintenance effort is any larger using a command pattern and swapping in a different command is as easy as changinge the class. The factory I've used should be used in freespaces example anyway, so the "scaffolding" doesn't differ greatly. I'd reckon that when it came to time to implement, the two are pretty much equal.

Share this post


Link to post
Share on other sites

Akin to a java.util.HashMap you canuse an array but the setup is the same type of thing in the storage.

With HashMap you use a loop ,

 

Because you may want to store an Object typing from the return method you can associate it with a short

unamed reference,

for(....){

meth_mapping.put(keyIs ,((int)MA());

YOU GET THEVALUE BACK WHEN YOU NAME THE KEY.value property of the hashmap

 

If your types are different for return in each key you will need to use a special <Vector> map.

 

Essentailly you can store the calls in an array or map vector e.t.c. but you won't be able to make it a

final array unless you init it with the methods ready of it would contradict since it contains a value to

return regardless of void.

The only catch is above can only be something like

int ret_number;

meth_mapping.put(keyIs ,(ret_number=MA());

Share this post


Link to post
Share on other sites

c'mon... you know you really want the hashmap to store strings of function names for functions with no parameters, and use RTI to find the function and call it.

 

It's a butt ugly solution, but youll learn heaps about RTI by doing it :) and so learn that it's uber powerful - and almost as dangerous (like most good aspects of programming should be!)

 

After that you'll know how to combine them both - declare the interface with the run method (as people have described above), but use RTI to build the hashmap dynamically at run time (eg from a properties file) instead of hard coding it - that way your application can be extended by plugins after you've released it.

Share this post


Link to post
Share on other sites

c'mon... you know you really want the hashmap to store strings of function names for functions with no parameters, and use RTI to find the function and call it.

 

It's a butt ugly solution, but youll learn heaps about RTI by doing it :) and so learn that it's uber powerful - and almost as dangerous (like most good aspects of programming should be!)

 

After that you'll know how to combine them both - declare the interface with the run method (as people have described above), but use RTI to build the hashmap dynamically at run time (eg from a properties file) instead of hard coding it - that way your application can be extended by plugins after you've released it.

What is RTI? (A quick google turned up naught). Is it like .NET Reflection?

Share this post


Link to post
Share on other sites

What is RTI? (A quick google turned up naught). Is it like .NET Reflection?

Yep - RTI - Runtime Type Inspection (sometimes RTTI), Really just another name for reflection.

 

My bad, I get hooked sometimes on private implementation issues (have worked with a company's 'rti' common code package in the past)

Share this post


Link to post
Share on other sites

What is RTI? (A quick google turned up naught). Is it like .NET Reflection?

Yep - RTI - Runtime Type Inspection (sometimes RTTI), Really just another name for reflection.

 

My bad, I get hooked sometimes on private implementation issues (have worked with a company's 'rti' common code package in the past)

 

Cool. Thanks.

 

Well in that case... Reflection is too slow :p

Share this post


Link to post
Share on other sites

Yeah I was going to post an example using RTI, but I couldnt remember the syntax. Java's reflection syntax is pretty gross.

 

kikz, I guess I was assuming the MA, MB, etc methods were operating on data and state in the current class. In that case, if you declare them inline, MA, MB are defined within the calling class, so they have automatic access to the state and variables of the calling class; whereas in the Command Pattern you are going to have to pass all that info into the external classes, and its going to get messy fast, especially if each method needs a different number and type of parameters.

 

If the MA, MB methods were totally independant methods, that didnt need any of the state of the calling class, *and* you're not using Java :), then id say Command Pattern would be just as neat.

 

For some reason I was imagining a gui class when i was thinking of this... and almost all usefull functions in a java gui class are going to need access to at least one of the privately declared GUI JComponents in the calling class.

Share this post


Link to post
Share on other sites

Yeah I was going to post an example using RTI, but I couldnt remember the syntax. Java's reflection syntax is pretty gross.

 

kikz, I guess I was assuming the MA, MB, etc methods were operating on data and state in the current class. In that case, if you declare them inline, MA, MB are defined within the calling class, so they have automatic access to the state and variables of the calling class; whereas in the Command Pattern you are going to have to pass all that info into the external classes, and its going to get messy fast, especially if each method needs a different number and type of parameters.

 

If the MA, MB methods were totally independant methods, that didnt need any of the state of the calling class, *and* you're not using Java :), then id say Command Pattern would be just as neat.

 

For some reason I was imagining a gui class when i was thinking of this... and almost all usefull functions in a java gui class are going to need access to at least one of the privately declared GUI JComponents in the calling class.

Bah that's what the MVC pattern is for :p (<3's patterns). Now you're assuming you put logic in the view.

 

Yeah, I get where you're coming from though :) Although, both methods will require putting the code for each method somewhere, be it in the same class as the form or in seperate classes.

 

Interesting you bring up the GUI thing. What happens if you want both command line and GUI interfaces? Better to have separation of concerns, or it get messy fast :)

 

Although my blatherings aren't specifically about what the OP was asking.

Share this post


Link to post
Share on other sites

actually kikz, totally OT, but maybe I can ask you something... I finished a small(130 hours) java gui project, which I attempted to make follow MVC. Im well up with MVC in a web context, having done a lot of rails, but in this case I had quite a bit of trouble with the views.

Seperating out models, easy as pie.

But views... in a web world, views are largly static, and all the interactions to change the view nessecarily have to come through the controller.

But in a desktop app, where the view changes the view(for want of a better phrase) I found it hard to shoehorn in the controller. Like, you click on something; that fires an event that is caught in the view. There will usually be one line in that event that gets a bunch of data from a model, via a controller, like MusicContoller.findAll(Tracks.class), cool. Then you inevitably have to do something with that data, like assigning it to a table, or throwing it into a text field, or whatever. Then you usually have to do a bunch of other things involving view objects - hiding things, showing things, selecting things etc.

So I ended up with no data logic in the view, but still heaps of logic. Every time I tried to move this out into the controller, I found that most of the logic was working on View objects, so I couldnt.

 

So whats the deal here? Do you pass view objects to the controller for manipulation? Then you have to make all the GUI elements publicly accessable, and that gets huge quickly. And if you do, do you pass the view object in to the controller every time, or do you perhaps make the Controller instance contain a private reference to a View?

 

It turned out more Model + (Controller/View), and I wasnt really happy with it.

Share this post


Link to post
Share on other sites

Thanks guys.

 

I've been trying for a while to reply but my internet sucks and hates this site. I stuffed up in my first post and meant to say that it needed to contain a one character key and an object, which was solved by new HashMap<Character, Object> though it took me ages to figure out that it was throwing errors with <char, Object> because char isn't the generic.

 

Anyway, thanks guys.

 

Edit: I totally used an interface system for the objects though :D

Share this post


Link to post
Share on other sites

actually kikz, totally OT, but maybe I can ask you something... I finished a small(130 hours) java gui project, which I attempted to make follow MVC. Im well up with MVC in a web context, having done a lot of rails, but in this case I had quite a bit of trouble with the views.

Seperating out models, easy as pie.

But views... in a web world, views are largly static, and all the interactions to change the view nessecarily have to come through the controller.

But in a desktop app, where the view changes the view(for want of a better phrase) I found it hard to shoehorn in the controller. Like, you click on something; that fires an event that is caught in the view. There will usually be one line in that event that gets a bunch of data from a model, via a controller, like MusicContoller.findAll(Tracks.class), cool. Then you inevitably have to do something with that data, like assigning it to a table, or throwing it into a text field, or whatever. Then you usually have to do a bunch of other things involving view objects - hiding things, showing things, selecting things etc.

So I ended up with no data logic in the view, but still heaps of logic. Every time I tried to move this out into the controller, I found that most of the logic was working on View objects, so I couldnt.

 

So whats the deal here? Do you pass view objects to the controller for manipulation? Then you have to make all the GUI elements publicly accessable, and that gets huge quickly. And if you do, do you pass the view object in to the controller every time, or do you perhaps make the Controller instance contain a private reference to a View?

 

It turned out more Model + (Controller/View), and I wasnt really happy with it.

I'd put view logic in the view. Given the intent that MVC is supposed to enable the ability to allow any view to be plugged in to the underlying model, there's no place but the view for view logic :)

 

I understand it's easy to say that, but when the code is gets complex or anything resembling real world code, it can become difficult to detmer what belongs where when you have complex interactions.

 

If you've got an example, I'd be happy to offer my opinion.

Share this post


Link to post
Share on other sites

All i care is that silly, Do as you should and trigger what you want by using a switch() inside a method called for the group of methods to choose.

Methods generally return a value, and even when they do not they are subjected to "doing some explicit action" at run-time , hence storage of unconstructed data and unpre-emptable actions means nothing and is worthless until it is a fix in a poorly allocated(more restricted) language such as javascript to solve some logic problems of availability and process access.

 

note: That method storage action was demonstrated in the early days of javascript as some sort of fix on holding values and showing the derrogative versitileness of javascript syntax as scripting. But you cannot using java.

Edited by nicephotog-jvm.net

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×