MLProgrammer-CiM
MLProgrammer-CiM

Reputation: 17257

Searching a List

Lets say I have a list and I am trying to look up a Class element in it, from which I only know one (unique) attribute.

public static List<Achievement> listAchievements;
String idAchievement = "5764e35";

This is obviously not working

listAchievements.indexOf(idAchievement );

Neither is this

Achievement ach(idAchievement);
listAchievements.getIndexOf(ach);

and the workaround is not pretty

 for (Achievement achievement : listAchievements) {
        if (achievement.resourceID().equalsIgnoreCase(idAchievement)) {
            // STUFF
            break;
        }
    }

Upvotes: 0

Views: 190

Answers (5)

Vipul
Vipul

Reputation: 836

1) you have to sort your list using static void sort(List,Comparator).
2) use static int binarySearch(List,Key,Comparator).

These two method are of java.util.Collections

Upvotes: 2

JB Nizet
JB Nizet

Reputation: 691625

There is no other way than to loop over the elements until you find the one you're looking for. You could use Guava's support for predicates:

Achievement a = Iterables.find(list, new Predicate<Achievement>() {
    @Override
    public boolean apply(Achievement input) {
        return input.resourceID().equalsIgnoreCase(idAchievement)
    }
});

but the end result is the same.

Or you could maintain a separate Map<String, Achievement> in addition to your list, or use a LinkedHashMap<String, Achievement> instead of your list, which would achieve O(1) search instead of O(n).

Upvotes: 4

Eugene Kuleshov
Eugene Kuleshov

Reputation: 31795

To make such efficient you'll either have to use Map of idAchievement to Achievement, or make sure your collection is sorted by idAchievement attribute and then use Collections.binarySearch().

Upvotes: 0

yshavit
yshavit

Reputation: 43391

What you have isn't a workaround, it's the solution.

You could abstractify it with lambda-like behavior, and this and that... but in the end, if you're trying to search a list for an element that has a given attribute, there's nothing you can do but to iterate over the list until you find an element with that given attribute.

If you need to find Acchievments by ID more directly, a Map<String,Achievement> might be a better choice if the IDs are unique (which you say they are).

Upvotes: 8

Jens Borgland
Jens Borgland

Reputation: 773

If you only have a list there's not much more to do. But if this is something that is done often you may want to consider creating a HashMap or similar instead (from achievementId to achievement).

Upvotes: 0

Related Questions