-2

My code is almost ready I just can't solve a simple problem. I want to add and identification code and the item attched to it in an ArrayList. Example, parentheses are just to clearify what I want to do, they are not part of code or output:

  • 3ZU2SD34: The Elder Scrolls (-! added)
  • 9ZU5SD54: Fifa 21 (-! added)
  • 3ZU2SD34: The Elder Scrolls (-! not added, ID already on the list)
  • 3ZU2SD34: Final Fantasy (-! not added, ID already on the list)
  • 4ZU8SD89: NBA 2K22 (-! added)

...and so on.

My code looks like this:

import java.util.ArrayList;
    import java.util.Scanner;

    public class Main {

        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            ArrayList<Item> items = new ArrayList<>();

            while (true) {

                System.out.println("Identifier? (empty will stop)");
                String identifier = scanner.nextLine();

                if (identifier.isEmpty()) {
                    break;
                }

                System.out.println("Name? (empty will stop)");
                String name = scanner.nextLine();

                if (name.isEmpty()) {
                break;
                }
                /*if (!items.contains(identifier)){   This doesn't work
                    items.add(new Item(identifier, name));
                }*/
                
                if (!items.contains(new Item(identifier,name))) {
                items.add(new Item(identifier, name));  //this works fine, but I want to skip even if only the ID is equal
                }
            }

            System.out.println("");
            System.out.println("==Items==");
            for (Item lines : items) {
               System.out.println(lines);
            }
        }
    }

Output:

Identifier? (empty will stop)
1234
Name? (empty will stop)
Test1
Identifier? (empty will stop)
1234
Name? (empty will stop)
Test2
Identifier? (empty will stop)
1234
Name? (empty will stop)
Test1
Identifier? (empty will stop)
5555
Name? (empty will stop)
Test3
Identifier? (empty will stop)


==Items==
1234: Test1
1234: Test2
5555: Test3

My code adds everything execpt identical Items, but I want it to skip same identification too. How can I do it? Probably there is such an easy way, but I can't figure it out.

Vincenzo
  • 9
  • 3
  • 3
    A `String` isn't an `Item`. So checking if a `String` is contained in a list of `Item`s will obviously never match. – M. Deinum Dec 13 '21 at 14:45
  • I edited it, I pasted my old code. Check it out again, but I get your point, how can I check if identifier is in the list? – Vincenzo Dec 13 '21 at 14:48
  • Instead of `contains` you could do something like `items.stream().anyMatch(i -> i.identifier.equals(name));` – 001 Dec 13 '21 at 14:54

2 Answers2

2

Your list contains an Item object whose .getIdentifier() method will return 1234.

That is, of course, not the same thing as the string 1234, therefore, trivially, contains returns false.

It's like me asking you: Hey, does this orchard of apple trees contain this painting of an apple? Of course it doesn't: The orchard contains no paintings.

You have to loop through the entire list yourself (write a for loop or use the stream API) to check. Java is OO and thus the notion that an object has an 'identifier' is not a general principle. That's something your Item class has, but not other classes.

Alternatively, your List<item> is probably not the right datatype if you want this; perhaps that should be a Map<String, String> that maps identifiers onto names. Then you can simply use .containsKey.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
0

you can overwirte Item's equals methods,like this code:

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Item item = (Item) o;
    return Objects.equals(identifier, item.identifier) ||
            Objects.equals(name, item.name);
}