1
import java.util.LinkedList;

public class GamesChallenge {

    private static LinkedList<Game> gameList = new LinkedList<>();

    public static void main(String[] args){

        //adding the games to the LinkedList

        addGame("Call of Duty", 300);
        addGame("Last day on Earth", 500);
        addGame("Fall Guys", 3000);
        System.out.println(gameList);

        //try to find the game in the LinkedList
        findGame("Fall Guys");

        //try to remove a game
        removeGame("Fall Guys");
        System.out.println(gameList);

    }

    public static void addGame(String name, int memory){
        // check if the song is in the linkedList
        Game game = new Game(name, memory);
        while(findGame(name) == false){
            //if the game does not exist then the game is added
            gameList.add(game);
            break;
        }

    }

    public static boolean findGame(String name){
        // check if the game is in the LinkedList
        if(gameList.indexOf(gameList.contains(name)) >= 0){
            //if the index is bigger or equal to 0 (the game is in the LinkedList) then it will return true
            return true;
        }
        //else it will return false
        else return false;
    }

 //here is where I have the problem
 
 public static void removeGame(String name){
     gameList.remove(gameList.indexOf(gameList.contains(name)));
 
 }
}


class Game {

    private String name;
    private int memory;

    public Game(String name, int memory){
        this.name = name;
        this.memory = memory;

    }

    @Override
    public String toString(){
        return name + ":" + memory;
    }

    public String getName() {
        return name;
    }

    public int getMemory() {
        return memory;
    }
}

I am new to programming and i am trying to learn. I tried to remove the game from the LinkedList but an error is thrown, the index is out of range and I do not understand why.

Sören
  • 1,803
  • 2
  • 16
  • 23
MsLaus
  • 21
  • 4
  • 1
    Please edit your post adding debugging details such as error message you got during compilation or runtime and also improved the formatting of the text. Reading [how to ask](https://stackoverflow.com/help/how-to-ask) and [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) will help you to edit your post – Gastón Schabas Jun 10 '23 at 19:55
  • Fix your code formatting. Either indent all lines four spaces, or wrap in a pair of triple back-ticks. – Basil Bourque Jun 10 '23 at 20:09
  • Is it your intention to use the _LinkedList_ class specifically, or would an alternate collection type suffice? – Reilas Jun 10 '23 at 21:34
  • `gameList.remove(gameList.indexOf(gameList.contains(name)))` doesn't begin to make sense. `contains()` returns a boolean, and your list doesn't contain booleans, and even if it did you don't need to search the list twice. What you appear to mean is simply `gameList.remove(gameList.indexOf(name))`. And you don't need a `while` loop when inserting. – user207421 Jun 11 '23 at 04:04
  • For your code `ArrayList` is the better choice (in fact, there are hardly any reasons to use `LinkedList`; it generally has worse memory use **and** worse performance). – Mark Rotteveel Jun 11 '23 at 12:20
  • @MarkRotteveel thank you for the comment. This is an exercise from a course I am taking so this was just a way for me to learn how to use LinkedLists. – MsLaus Jun 13 '23 at 08:39
  • @Reilas i wanted to use the LinkedList class because this is just an exercise from the course I am taking. – MsLaus Jun 13 '23 at 08:42

4 Answers4

0

gameList.contains(name) returns a boolean indicating whether or not name is found in the List. Calling gameList.indexOf on that boolean will always return -1 because a Game object is never equal to a boolean.

You can instead use List#removeIf to remove based on the condition of the name of the game being equal to the parameter.

public static void removeGame(String name){
    gameList.removeIf(g -> g.getName().equals(name));
}

The other methods are also implemented erroneously, having similar issues. You could use streams or an enhanced for loop to check for a game with a matching name.

public static boolean findGame(String name){
    return gameList.stream().anyMatch(g -> g.getName().equals(name));
}
public static void addGame(String name, int memory){
    if (!findGame(name))
        gameList.add(new Game(name, memory));
}
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
0

Problem:

gameList.contains(name)

returns true or false

gameList.indexOf(gameList.contains(name))

you are trying to find index of a boolean which returns -1.

And you are trying to remove value at -1 index hence getting IndexOutBoundException.

Solution:

Apart from above problem I found several other problems. So sharing working code. You'll find

"// --- Modified:" comments with description where ever I've made changes

class GamesChallenge {

private static LinkedList<Game> gameList = new LinkedList<>();


public static void addGame(String name, int memory){
    // check if the song is in the linkedList
    Game game = new Game(name, memory);
    // --- Modified: Removed while loop as it is unecessary
    //  and modified condition to check index
    if(findGame(name) == -1){
        //if the game does not exist then the game is added
        gameList.add(game);
    }

}

public static void removeGame(String name){
    // --- Modified: We check the index and then 
    //  perform remove operation
    int index = findGame(name);
    if(index >= 0)
        gameList.remove(index);
}

public static int findGame(String name){
    // --- Modified: You are storing objects in linkedlist 
    // so to find index yoy have to pass the object reference.
    // I've simplified this method
    
    // Loop through all the element
    for(int i = 0; i < gameList.size(); i++){
        // check if name matches then return index
        if(gameList.get(i).getName().contains(name))
            return i;
    }
    return -1;
}

public static void main(String[] args) {
    //adding the games to the LinkedList

    addGame("Call of Duty", 300);
    addGame("Last day on Earth", 500);
    addGame("Fall Guys", 3000);
    System.out.println(gameList);

    //try to find the game in the LinkedList
    findGame("Fall Guys");

    //try to remove a game
    removeGame("Fall Guys");
    System.out.println(gameList);
}
}
rex50
  • 41
  • 4
0

Generally, either contains(Game g) or indexOf(Game g) is needed. If you need to know where in the LinkedList (or any List) the item is, use indexOf. If you only need to know if the item is in the List, use contains. Per the language docs, if the Object (Game, in this case) is not in the list, contains returns false while indexOf returns -1.

Importantly, both methods use Objects.equals, which uses Game.equals in turn. Since Game does not override the inherited Object.equals, neither contains nor indexOf will work as expected here. (Note that overriding equals has additional requirements, as explained here).

Finally, contains(String name) on a List<Game> will always* return false since a Game can not be equal to a String.

*There is an edge case if both values are null that may yield different results.

Naomi R
  • 101
  • 1
  • 2
-1

If I run your code, I get the following output.

[Call of Duty:300, Last day on Earth:500, Fall Guys:3000]
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: -1, Size: 3
    at java.base/java.util.LinkedList.checkElementIndex(LinkedList.java:559)
    at java.base/java.util.LinkedList.remove(LinkedList.java:529)
    at GamesChallenge.removeGame(GamesChallenge.java:49)
    at GamesChallenge.main(GamesChallenge.java:20)

The stack-trace here shows that the last instruction from the GamesChallenge class, was the removeGame method call.

In which, on line 49 had made a call to LinkedList#remove.

gameList.remove(gameList.indexOf(gameList.contains(name)));

It appears that you are trying to locate a value with gameList, and if it exists, remove it.

Since the removeGame has a name parameter, you'll need to iterate on gameList, and remove the match.
Note, this will remove only the first match.
Remove the break keyword to have it remove all matches.

public static void removeGame(String name){
    for (Game game : gameList) {
        if (game.getName().equals(name)) {
            gameList.remove(game);
            break;
        }
    }
}

Output

[Call of Duty:300, Last day on Earth:500, Fall Guys:3000]
[Call of Duty:300, Last day on Earth:500]

Furthermore, there is a semantic error on line 38.

if(gameList.indexOf(gameList.contains(name)) >= 0)

Again, you'll want to iterate on gameList and check for a match.

public static boolean findGame(String name){
    // check if the game is in the LinkedList
    for (Game game : gameList) {
        if (game.getName().equals(name)) return true;
    }
    return false;
}
Reilas
  • 3,297
  • 2
  • 4
  • 17