简体   繁体   中英

How do I remove an element the user input from an ArrayList when it contains both strings and integers?

I'm new to coding and I'm quite confused of how this ArrayList work.

I have the [Java] code:

ArrayList<Object> allCards = new ArrayList<Object>();

allCards.add(2);
allCards.add(2);
allCards.add(3);
allCards.add('K');
allCards.add('J');

Printing out the allCards ArrayList, I have:

[2, 2, 3, K, J]

Right now, I need to take in an user input, and remove the user input from this ArrayList. How do I do that?

I could use

Scanner scan = new Scanner(System.in);
int i = scan.nextInt();

allCards.remove(new Integer(i));

if the ArrayList only contains integers, but the user input could be either a char or an int, how do I remove that from the ArrayList?

Also, if there are two of the same user input in the ArrayList like the number 2, I would only like to remove one of them.

Thank you.

I think your problem can be solved if you just use ArrayList with String type like:

    ArrayList<String> allCards = new ArrayList<String>();

About how to remove the element in the array list, you can get an input from user in String, then compare it to elements in the array list. When you use the remove() method if the input string matches (case-sensitive) the element, it will only remove the first occurrence, if not, it does not thing. You can test this code:

    ArrayList<String> allCards = new ArrayList<String>();
    allCards.add("2");
    allCards.add("2");
    allCards.add("3");
    allCards.add("K");
    allCards.add("J");

    System.out.println("The Array List before user input: ");
    for (String card : allCards) {
        System.out.print(card + " ");
    }
    System.out.println();
    Scanner scanner = new Scanner(System.in);
    System.out.print("Input to remove from Array List: ");
    String input = scanner.nextLine();
    allCards.remove(input);

    System.out.println("The Array List after user input: ");
    for (String card : allCards) {
        System.out.print(card + " ");
    }
    scanner.close();

So you want to be able to read either an int or a char from the input. I guess you will have to define a syntax for your input string, that would allow you to decide if it's an int or a char . You can use a regexp for that.

Example:

private static final Pattern RE
        = Pattern.compile("^\\s*(?:([0-9]+)|'(.)')\\s*");

    Scanner scanner = new Scanner(System.in);
    String s = scanner.nextLine();
    Matcher matcher = RE.matcher(s);
    if (!matcher.matches()) {
        System.out.println("Bad input");
    } else {
        Object key;
        if (matcher.group(1) != null) {
            key = Integer.valueOf(matcher.group(1));
        } else {
            key = matcher.group(2).charAt(0);
        }
        allCards.remove(key);
        System.out.println(allCards);
    }

There are two parts of this question, first you need to correctly read a character or an integer and then remove that from the list. First line by line and convert into int or char then use iterator to loop through the list and remove the object and break.

public static void main(String[] args) {
        List<Object> allCards = new ArrayList<>();
        allCards.add(2);
        allCards.add(2);
        allCards.add(3);
        allCards.add('K');
        allCards.add('J');
        Scanner scan = new Scanner(System.in);
        while (true) {
            String line = scan.nextLine();
            try {
                int num = Integer.parseInt(line);
                for(Iterator<Object> it = allCards.iterator(); it.hasNext(); ) {
                    Object o = it.next();
                    if ((o instanceof Integer) && (Integer) o == num) {
                        allCards.remove(o); break;
                    }
                }
            } catch (Exception ex) {
                char c = line.charAt(0);
                for(Iterator<Object> it = allCards.iterator(); it.hasNext(); ) {
                    Object o = it.next();
                    if ((o instanceof Character) && (Character) o == c) {
                        allCards.remove(o); break;
                    }
                }
            }
        }
    }

You can extend it to support more objects types.

Supposing you can not change the type of the array allCards you have to cast the input to both Integer and Character and check if they are contained in the list:

        final List<Object> allCards = new ArrayList<Object>();

        allCards.add(2);
        allCards.add(2);
        allCards.add(3);
        allCards.add('K');
        allCards.add('J');

        final Scanner scanner = new Scanner(System.in);
        final String i = scanner.nextLine();

        try {
            allCards.remove(Integer.valueOf(i));
        } catch(NumberFormatException e) {
            // safe to ignore
        }
        allCards.remove(Character.valueOf(i.charAt(0)));
        
        scanner.close();

But if you are implementing some kind of card game you should consider introducing a class or enum of type card and work with a strong typed list of cards. For example like this:

    final List<Card> allCards = new ArrayList<Card>();
    allCards.add(new Card(CardValue.C2));
    allCards.add(new Card(CardValue.C2));
    allCards.add(new Card(CardValue.C3));
    allCards.add(new Card(CardValue.CK));
    allCards.add(new Card(CardValue.CJ));

    playCard(allCards);

    System.out.println("The Array List after user input: ");
    for (Card card : allCards) {
        System.out.print(card.getValue() + " ");
    }

    private void playCard(List<Card> allCards) {
        final Scanner scanner = new Scanner(System.in);
        final String i = scanner.nextLine();
        scanner.close();

        final CardValue cardValue = CardValue.getCardValue(i);
        final Optional<Card> foundCard = allCards.stream().filter(c -> c.getValue() == cardValue).findAny();

        if (foundCard.isPresent()) {
            allCards.remove(foundCard.get());
        } else {
            throw new IllegalArgumentException("You have no card with value " + i);
        }

    }

    private class Card {
        private final CardValue value;

        private Card(CardValue value) {
            this.value = value;
        }

        private CardValue getValue() {
            return value;
        }

    }

    private enum CardValue {
        C2("2"),
        C3("3"),
        // all other values ...
        CJ("j"),
        CK("k");

        private final String value;

        CardValue(String value) {
            this.value = value;
        }

        public CardValue getCardValue(String value) {
            for (CardValue c : CardValue.values()) {
                if (c.value.equals(value.toLowerCase().substring(0, 1))) {
                    return c;
                }
            }
            throw new IllegalArgumentException("Illegal card value " + value);
        }
    }

Have fun!

You can use Collection.removeIf :

allCards.removeIf(obj -> obj instanceof Integer);

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