How to shuffle characters from a Java string randomly?

Asked

Viewed 3,711 times

6

I’m developing a password generator program. In it the user can set the percentage of numbers, letters and special characters that he wants to have in his password, as well as the size of his password. Later I concatenate the numbers, letters and symbols and need to shuffle them in order to look like a password (this was the best solution I could find to generate passwords following this concept of percentage of characters).

The problem is that I need to shuffle a character array randomly.

This array can be an array of char, or even a String, the important thing is that I have to print this on the screen so shuffled later.

Researching a little, I found the function shuffle(); class Collecions and wrote the following code, which does just what I want:

public static String shuffleString(String s) {
    List<String> letters = new ArrayList<String>();
    String temp = "";

    for (int i = 0; i < s.length(); i++) {
        letters.add(String.valueOf(s.charAt(i)));
    }
    System.out.println("");

    Collections.shuffle(letters);

    for (int i = 0; i < s.length(); i++) {
        temp += letters.get(i);
    }
    return temp;
}

The problem is that I find this code a little "heavy". I think there must be some simpler way to do this. I have also been concerned about how these items are shuffled, because I need something random, or as random as possible.

  • The problem here is somewhat like the syntax of Java. I find the code too extensive to do something simple. I think I’m doing this the wrong way or else in an inefficient way.

3 answers

6

How about using Java 8?

public static String shuffle(String s) {
    List<Character> letters = s.chars().boxed().map(c -> (char) c.intValue()).collect(Collectors.toList());
    Collections.shuffle(letters);
    StringBuilder t = new StringBuilder(s.length());
    letters.forEach(t::append);
    return t.toString();
}
  • I am using jdk 1.7.0_51, I have no way to test it here. I would know if there is a similar solution that works in 1.7?

5


Abusing a little bit of regex:

public static String shuffle(String s) {
    List<String> letters = Arrays.asList(s.split(""));
    Collections.shuffle(letters);
    StringBuilder t = new StringBuilder(s.length());
    for (String k : letters) {
        t.append(k);
    }
    return t.toString();
}

Watch it run on ideone.

  • 1

    Perfect, this is exactly what I needed. Much cleaner than my code. Thank you very much! :)

4

Come on then:

public static String shuffleString(String s) {
    char[] caracteres = s.toCharArray();
    ArrayList<String> lista = new ArrayList<String>(Arrays.asList(caracteres));
    Collections.shuffle(lista);
    return lista;

}
  • The return of the method is String, but you are returning ArrayList<String>, which gives build error. Also, the Arrays.asList works only for object type arrays and not for primitive type arrays.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.