0

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... :/

2Pacho
  • 134
  • 9
  • 3
    *My fastest solution would be to write an "for" that goes arround the arrayList* -- yes you can do that or use binary search if the name is ordered. since this problem falls into searching problem. – Bagus Tesa May 04 '17 at 01:55
  • Your 'checkPlayer' can return what it found instead of you traversing the list twice. Additionally you may want to consider data structures other than a List to keep track of membership. – pvg May 04 '17 at 01:56

3 Answers3

1

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.

Community
  • 1
  • 1
e4c5
  • 52,766
  • 11
  • 101
  • 134
1

Try using a hashtable with a key, it would be much more efficient!

apache
  • 35
  • 1
  • 1
  • 8
0

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;
            }
        }
frank
  • 52
  • 4