For your particular purpose, with Java 8 Streams, you don't even need a loop.
String[] letters = IntStream.rangeClosed('a', 'z').mapToObj(i -> Character.toString((char)i)).toArray(String[]::new);
System.out.println(Arrays.toString(letters));
To break it down:
IntStream.rangeClosed(int, int) makes a Stream of ints from the first int to the second, inclusive of both endpoints. We use this because there is no CharStream class (for some reason), but we can still use chars 'a' and 'z', which will be implicitly converted to their int value.
mapToObj takes a function which will convert each int of the Stream into an object. It gets a little messy here, as there is no single step conversion from int to String, we first need the int interpreted as a character value. So, we cast each int (named i) to a char, and then wrap that in a conversion from char to String: i -> Character.toString((char)i). This will leave us with a Stream<String>.
- Now, we want the output to be
String[], as per your question. Stream has a toArray method, but this will give us an annoying Object[] result. Instead, we will supply the method we want to have used to build the array. We don't want anything fancy, so we'll just use the standard initializer for a String array: toArray(String[]::new).
After that, letters will be equal to an array of Strings, and each one will successively be a letter from a to z.
If you don't have access to Java 8 or simply don't like the above solution, here's a simplified version of your above code that removes the need for the index:
String[] letters = new String[26];
for (char c = 'a'; c <= 'z'; c++) letters[c - 'a'] = Character.toString(c);
System.out.println(Arrays.toString(letters));
In Java, chars can be treated as ints because below the surface, they are both stored as numbers.
int i = 0;outside the loop