Milie
Milie

Reputation: 435

Using a LinkedHashSet to store random numbers but has duplicates

I have an app that generates a random arithmetic expression. It then generates a correct answer in a random position (tag) and three subsequent incorrect answers allowing the user to choose.

I originally went with an ArrayList but it provides duplicates. I then converted the ArrayList contents in the for loop to a Set and it still produced duplicates. I then changed the initial ArrayList to a LinkedHashSet and alas, still duplicates. i'm thinking it might be the placement in my for loop but I've tried messing around with position and I either encounter duplicates or Index problems.

I don't want to use Java 8's:List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList()); as it's API/Version specific.

For Loop Code:

    List<Integer> answers = new ArrayList<>(new HashSet<Integer>(5));
    answers.clear();

    int incorrectAnswer;

    for (int i = 0; i < 4; i++) {
            if (i == locCorrectAnswer) {
                answers.add(value);
            } else {
                if (operator == '+') {
                    incorrectAnswer = value + rand.nextInt(10) + 1;
                } else {
                    incorrectAnswer = value - rand.nextInt(10) + 1;
                }
                while (incorrectAnswer == value) {
                    if (operator == '+') {
                        incorrectAnswer = value + rand.nextInt(10) + 1;
                    } else {
                        incorrectAnswer = value - rand.nextInt(10) + 1;
                    }
                }
                answers.add(incorrectAnswer);
            }
    }

For Loop code (with ArrayList and conversion to Set):

    ArrayList <Integer> answers;
    Set<Integer> s = new LinkedHashSet<>(answers);

    int incorrectAnswer;

    for (int i = 0; i < 4; i++) {
            if (i == locCorrectAnswer) {
                answers.add(value);
            } else {
                if (operator == '+') {
                    incorrectAnswer = value + rand.nextInt(10) + 1;
                } else {
                    incorrectAnswer = value - rand.nextInt(10) + 1;
                }
                while (incorrectAnswer == value) {
                    if (operator == '+') {
                        incorrectAnswer = value + rand.nextInt(10) + 1;
                    } else {
                        incorrectAnswer = value - rand.nextInt(10) + 1;
                    }
                }
                answers.add(incorrectAnswer);
            }
            s.addAll(answers);
            answers.clear();
            answers.addAll(s);
    }

I'm sure its a simple error but I can't see it.

Upvotes: 1

Views: 181

Answers (3)

gagan singh
gagan singh

Reputation: 1611

You can also try the following.

Set<Integer> s = new HashSet<>();
//correct value
s.add(value);
while (s.size() < 4)
{
    //incorrect value
    s.add( value + rand.nextInt(10) + 1);
}
List<Integer> answers = new ArrayList<>(s);
//shuffle
Collections.shuffle(answers);

Upvotes: 1

LenglBoy
LenglBoy

Reputation: 1451

Just create your Set of answers like this:

Set<String> answers = new LinkedHashSet<String>();

Now every value can be there just 1 time. It can be added without getting an error but it will be only one time in the list. And you can still iterate/loop through it.

Upvotes: 1

OhleC
OhleC

Reputation: 2950

You're still calling answers.addAll(s) in the loop. While there won't be any duplicates in s in any given iteration, you will still get duplicates from different iterations.

Since you don't want any duplicates, there's no reason to use Lists in the first place. Any Set will remove duplicates, and LinkedHashSet will preserve insertion order.

Upvotes: 0

Related Questions