The code is using the class java.util.Random
, which is a native Java class for random number generation.
The problem is that you have created a class with the same name (Random
), and then the compiler tries to find the methods setSeed
and nextInt
in its class. And since these methods do not exist, it gives the build error.
So the first thing to do is to change the name of your class to anything other than Random
. And don’t forget to do the import
class java.util.Random
also:
import java.util.Random;
public class TestRandom { // mude o nome da classe para outro que não seja Random
private static final Random gerador = new Random();
public static void main(String[] args) {
// agora tudo compila
gerador.setSeed(4);
System.out.println((char) ('a' + Math.abs(gerador.nextInt() % 26)));
}
}
As for the method setSeed
, well, it changes the Seed of the object Random
.
In summary, the numbers generated by this class are not purely random. In fact they are pseudo-random, because what happens internally are various calculations that generate numbers that seem like random.
And all these calculations start from an initial value, called Seed. If two objects Random
are created with the same Seed, they will generate the same sequence. See documentation for more details.
That said, use setSeed
and always pass the same value, as you did, will result in the same number being generated every time this code is executed.
If you want the result to be more random and not the same every run, you do not need to use setSeed
. When you create a new object Random
(with new Random()
), it is already initialized with a Seed that, according to the documentation, is "very likely to be different from any other invocation of this constructor".
As to his last doubt, the number resulting from the expression Math.abs(...)
is not being concatenated to char
, and yes added.
This happens because a char
- briefly - can also be treated as a number. Ex:
char c = 'a';
System.out.println((int) c); // 97
By doing the cast for int
, is printed 97
, which is the value of Codepoint corresponding to the character a
(on this link the value of Codepoint is U+0061
, since Unicode uses hexadecimal values - to better understand how codepoints of Unicode, I suggest reading of this article and of this question).
It is also possible to pass a numerical value directly by doing the cast for char
, and the result is the character whose Codepoint has that numerical value. Ex:
char c = (char) 39321;
System.out.println(c); // 香
In this case, the char
will have the character that corresponds to the Codepoint 39321 (in this case, the character 香
- and see again on this link that the value is in hexadecimal: U+9999
).
And as a char
can be manipulated as number, we can also add a value to the same:
char c = 'a' + 1;
System.out.println((int) c); // 98
System.out.println(c); // b
This code prints out:
98
b
That is, by adding 1
to the character a
, the result is the Codepoint corresponding to a
(that we have seen that it is 97) added to the number 1, which is 98. So the char
becomes the character corresponding to Codepoint 98, which is the letter b
.
So what your code does is get a letter between a
and z
, since the result of % 26
always returns a number between 0 and 25 (when it is zero, the result will be itself a
, and when it’s 25, it’ll be z
). This is only possible because the codepoints these characters are sequential: the Codepoint of the letter b
is exactly 1 above the a
, the c
is 1 above the b
, etc.. See this link for more details.
Another option to do the same thing is pass a parameter to nextInt
, indicating the maximum value that can be returned:
System.out.println((char) ('a' + gerador.nextInt(26)));
With nextInt(26)
, the result is an integer between zero and 25. This eliminates the need to use % 26
and Math.abs
.