Ray25Lee
Ray25Lee

Reputation: 65

Java - Shuffling Elements and Outputting Specific Amounts

In Java, I was just told to use this structure for shuffling a list of items:

List<String> tasks = Arrays.asList("1","2","3","4","5","6","7","8");
Collections.shuffle(tasks);
for(String task : tasks){
    System.out.println(task); 
}

The problem with this solution for my program is I only want to randomly output a number of elements as chosen by the user (meaning, if the user wants only five elements instead of all eight, I want only five of the elements randomly outputted). I've never actually used a lambda or that form of forloop before (I'm completely new to Java). I know how to use arrays, and I tried finding a shuffle option for arrays but came up with nothing. I also tried this:

int num = console.nextInt();
List<String> tasks = Arrays.asList("1","2","3","4","5","6","7","8");
Collections.shuffle(tasks);
for(int i = 1; i <= num; i++){
    String task = tasks;
    System.out.println(task); 
}

But obviously, this format is very, very incorrect (mainly because, again, I don't know how that format works). How can I get the list shuffled AND output ONLY the amount of elements the user wants?

Note: I do NOT have Java 8.

Upvotes: 0

Views: 244

Answers (6)

Tim Biegeleisen
Tim Biegeleisen

Reputation: 522541

Would there be anything wrong with shuffling the initial 8 elements (randomly), and then simply returning a subset of that list? Consider the following code:

public class ListTest {
    public static List<String> getRandomItems(int num) {
        List<String> tasks = Arrays.asList("1","2","3","4","5","6","7","8");
        Collections.shuffle(tasks);

        return tasks.subList(0, num);
    }

    public static void main(String[] args) {
        // take 5 random elements
        List<String> randomList = getRandomItems(5);
        for (String item : randomList) {
            System.out.println("Found an item: " + item);
        }
    }
}

Note that it should not matter which subset of the original 8 elements you take since they will be in a random order. Rather, the only thing which should matter is that you choose the correctly-sized subset.

Upvotes: 4

Kagemusha
Kagemusha

Reputation: 288

Your second code example wouldn't even compile because you cannot assing a List<String> to a String. You'd have to use String task = tasks.get(i);

If you want to output random elements from the list you can just use Randomto get a random number in the range 0 to list.size() and output the element at the corresponding position:

List<String> tasks = Arrays.asList("1","2","3","4","5","6","7","8");
Collections.shuffle(tasks);
int num = 5;
Random random = new Random();

for(int i = 0; i < num; i++){
    System.out.println(tasks.get(random.nextInt(tasks.size())));
}

The problem here is that you might output the same element multiple times because of the (pseudo-)randomly generated number. A way to fix this problem is to use a Set, which does not allow duplicates, and fill it until you have enough unique elements from your list:

List<String> tasks = Arrays.asList("1","2","3","4","5","6","7","8");
Collections.shuffle(tasks);
int num = 5;
Random random = new Random();
Set<String> selectedTasks = new HashSet<String>();

do {
    selectedTasks.add(tasks.get(random.nextInt(tasks.size())));
} while (selectedTasks.size() < num);

System.out.println(selectedTasks);

Upvotes: 0

Scary Wombat
Scary Wombat

Reputation: 44854

Another way to skin the cat

int num = console.nextInt();
for(String task : tasks){
    System.out.println(task); 

    if (num--) <= 0) break;
}

Upvotes: 0

Bethany Louise
Bethany Louise

Reputation: 646

tasks is a List, which can't be assigned to a String. You need to get a specific String from tasks to assign to task - or you could just do away with task altogether because it isn't necessary to declare a separate variable for it. Your for loop should look like this:

for (int i=0; i<num; i++) {
    System.out.println(tasks.get(i));
}

Note that I also changed int i=1; i<=num; from your code to int i=0; i<num;. Indices begin at 0, so it's generally good practice to begin your loop at 0, as you'll be calling tasks.get(0), tasks.get(1), and so on.

Upvotes: 2

After the shuffle ask the user how many elements does he need... then use List.sublist from 0 to the given number

Example:

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    List<String> tasks = Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8");
    Collections.shuffle(tasks);
    System.out.println("how many do you need??");
    int userAnswer = sc.nextInt();
    List<String> res = tasks.subList(0, userAnswer);
    System.out.println("here are " + res);
}

Upvotes: 0

MikeCAT
MikeCAT

Reputation: 75062

After shuffling the list, you can get elements from the head via Iterator.

int num = console.nextInt();
List<String> tasks = Arrays.asList("1","2","3","4","5","6","7","8");
Collections.shuffle(tasks);
java.util.Iterator<String> taskItr = tasks.iterator();
for(int i = 1; i <= num && taskItr.hasNext(); i++){
    String task = taskItr.next();
    System.out.println(task); 
}

Upvotes: 0

Related Questions