Reputation: 7898
I have two classes, Foo and Bar. Each Foo has a name and a bunch of items. Bar contains a bunch of Foo's, each with a unique name.
Bar has a method, AddEntry that takes a fooName and an item (1) if a foo with fooName is already in the Bar, adds another item to the Foo or (2) if a foo with fooName is not in the Bar, creates a Foo with that name and add the item to the new Foo.
This is an outline of how I'm implementing. Is there a better way? I'm just learning Java, but this seems clunky
class Foo { // a name and some items
String fooName;
List<Object> items = new ArrayList<Object>;
Foo(name) {...} // create a named Foo
AddtoFoo(item) {...} // add an item to this Foo
}
class Bar { // a bunch of foo's
List<Foo> fooList = new Arraylist<Foo>;
void AddEntry(String fooName, Object item) {
boolean member = false;
for(Foo foo : fooList){
if{foo.name == fooName) {
member = true;
foo.AddtoFoo(item); // adds an item to this foo
break;
}
}
if(member == false) {
Foo foo = new Foo(fooName); // creates a named foo
foo.AddtoFoo(item); // adds the item
fooList.add(foo); // maintain our list of foo's
}
}
}
Upvotes: 0
Views: 593
Reputation: 1763
The best way and more maintainable way would be to use hashCode and use contains.
public int hashCode() { return fooName.hashCode(); }
This is must faster than for: loop. Althought it doesn't provide you O(1) complexity but it guarantees (theoretically) fixed retrieval ~ O(1)
Also get() method does the same on hashMap. It uses hashCode to retrieve the object from the Map.
Upvotes: 0
Reputation: 2725
This is correct but if your are looking for the right foo object, instead of using a List
, use a Map
, like the HashMap
. Use as key the fooName
and as value the Foo
object. Get the object you are looking with get(fooName)
and if returns null, does not exists and the add a new Foo
with put()
.
Upvotes: 0
Reputation: 22415
You probably want to use a Map
instead, which you can look up an object by a key.
Map<String,Foo> fooMap = new HashMap<String,Foo>();
foo.put("name_of_foo",new Foo());
Then your addEntry
might look like this:
void addEntry(String fooName, Object item){
Foo foo = fooMap.get(fooName);
if(foo == null){
foo = new Foo();
fooMap.put(fooName,foo);
}
foo.addToFoo(item);
}
Also, you should compare String
equality by using foo.name.equals(fooName)
Upvotes: 2
Reputation: 691675
Unless the foo must stay in the same order, you could replace your list of foos with a Map<String, Foo>
. Searching for an existing foo would become a O(1) operation rather than a O(n) operation.
Even if the foos must stay ordered, you could use a LinkedHashMap.
Upvotes: 1
Reputation: 14149
If foo's name is just there for the lookup, perhaps a Map<String,List<Foo>>
(and removing Foo.name) would save you from coding that much.
Upvotes: 2
Reputation: 7332
You could try using a HashMap in Bar, instead of using a List. Use the fooName as unique key. This way, in Bar you can check if the instance of Foo is already known in your current bar much faster (just something along the lines of this):
Map<String, Foo> fooMap = new HashMap<String, Foo>();
...
Foo foo = fooMap.get(fooName);
if(foo == null)
{
fooMap.add(fooName, new Foo(fooName));
}
Upvotes: 1
Reputation: 788
In bar class you should use HashMap instead of ArrayList with FooName as key and Foo as pair. Since HashMap has o(1) searchingtime which you are doing with a for loop itreation in arraylist.
Upvotes: 2
Reputation: 88707
I'd use a Map<String, Foo>
to map the foo name to a foo object.
Map<String, Foo> fooMap = new HashMap<String, Foo>();
Thus you could do
Foo foo = fooMap.get(fooName);
if( foo == null)
{
foo = new Foo(fooName);
fooMap.put(fooName, foo);
}
foo.AddtoFoo(item);
Upvotes: 2