简体   繁体   中英

Java ArrayList trying to check if object with this name exists

I'm having a bit of trouble in my head trying to solve this: I'm working on a "rankList", an arrayList made of "Score". Score it's the object that has the following atributes: name,wins,loses,draws. My class Ranking has an ArrayList of Score objects. To create a new Score object I just use the name (and set the rest to 0 since it's new). However I'm trying to check if the player's name it's already in rankList I don't have to create new but sum a win or lose or draw. I have been reading arround that I have to override equals then others say I have to override contains... It's getting a big mess in my head. My fastest solution would be to write an "for" that goes arround the arrayList and use the getName().equals("name"); however this is getting too messi in my code. I have checkPlayer (if the palyer is in the list):

 public boolean checkPlayer(String playerName) {
    for (int i = 0; i < this.rankList.size(); i++) {
        if (this.rankList.get(i).getName().equals(playerName)) {
            return true;

        }
    }
    return false;
}

then if I want to incrase the wins i have this :

public void incraseWins(String playerName) {
    if (checkPlayer(playerName)) {
        for (int i = 0; i < this.rankList.size(); i++) {
            if (this.rankList.get(i).getName().equals(playerName)) {
                this.rankList.get(i).setWins(this.rankList.get(i).getWins() + 1);
                break;
            }
        }
    } else {
        createPlayer(playerName);
    //more for to get to the player i'm looking for...
        for (int i = 0; i < this.rankList.size(); i++) {
            if (this.rankList.get(i).getName().equals(playerName)) {
                this.rankList.get(i).setWins(this.rankList.get(i).getWins() + 1);
                break;
            }
        }

    }

So i guess there is a better way to do this... :/

ArrayList is not the right data structure here. To check if an element exists in the array you are searching the entire arraylist. Which means it's O(N).

To keep an array list is sorted order and do a binary search on it would definitely be faster as suggested in the comments. But that wouldn't solve all your problems either because insert into the middle would be slow. Please see this Q&A: When to use LinkedList over ArrayList?

One suggestion is to use a Map . You would then be storing player name, player object pairs. This would give you very quick look ups. Worst case is O(log N) i believe.

It's also worth mentioning that you would probably need to make a permanent record of these scores eventually. If so an indexed RDBMS would give you much better performance and make your code a lot simpler.

尝试使用带有键的哈希表,它将更加高效!

e..Why not using map<>.

a binary search is good idea if you must use List,code like this

    List<Method> a= new ArrayList<>();
    //some method data add...
    int index =  Collections.binarySearch(a, m);
    Method f = a.get(index);

and class method is impl of Comparable,then override compareTo() method

public class Method implements Comparable<Method>{
........
@Override
public int compareTo(Method o) {
    return this.methodName.compareTo(o.getMethodName());
}

if you don't want use binsearch,CollectionUtils in commons can help you

        CollectionUtils.find(a, new Predicate() {
        @Override
        public boolean evaluate(Object object) {
            return ((Method)object).getMethodName().equals("aaa");
        }
    });

in fact CollectionUtils.find is also a 'for'

 for (Iterator iter = collection.iterator(); iter.hasNext();) {
            Object item = iter.next();
            if (predicate.evaluate(item)) {
                return item;
            }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM