Java Tutorial

How to Convert Letters to Numbers in Java — Code Examples

AlphaCoder Team|May 23, 2026|11 min read

Java provides several robust ways to convert letters to numbers, from simple char arithmetic to the Character utility class and modern streams API. Whether you need alphabet positions (A=1 through Z=26) or raw ASCII values, Java handles both elegantly. If you want to skip the code and convert instantly, our letters to numbers converter runs right in your browser.

Method 1: Simple char Arithmetic

In Java, char is a numeric type. You can subtract characters directly to get numeric offsets. This is the most common approach for converting a letter to its alphabet position.

public class LetterToNumber {

    // Convert a single letter to its alphabet position (A=1, Z=26)
    public static int letterToPosition(char letter) {
        return Character.toUpperCase(letter) - 'A' + 1;
    }

    // Convert a position back to a letter
    public static char positionToLetter(int position) {
        if (position < 1 || position > 26) {
            throw new IllegalArgumentException("Position must be 1-26");
        }
        return (char) ('A' + position - 1);
    }

    public static void main(String[] args) {
        System.out.println(letterToPosition('A'));  // 1
        System.out.println(letterToPosition('Z'));  // 26
        System.out.println(letterToPosition('m'));  // 13

        System.out.println(positionToLetter(1));    // A
        System.out.println(positionToLetter(26));   // Z
    }
}

The key insight: 'A' has the integer value 65 in Java (its ASCII code). Subtracting 'A' from any uppercase letter gives a zero-based index, and adding 1 converts it to a one-based position. Check the full reference on our ASCII converter page.

Method 2: Using the Character Class

Java's Character class provides utility methods for validation and conversion. This approach is more defensive and production-ready.

public class CharacterClassExample {

    public static int safeLetterToPosition(char c) {
        if (!Character.isLetter(c)) {
            return -1;  // Not a letter
        }
        return Character.toUpperCase(c) - 'A' + 1;
    }

    public static int getAsciiValue(char c) {
        return (int) c;  // Returns full ASCII value
    }

    public static void main(String[] args) {
        // Alphabet position (A1Z26)
        System.out.println(safeLetterToPosition('H'));  // 8
        System.out.println(safeLetterToPosition('5'));  // -1 (not a letter)

        // Raw ASCII values
        System.out.println(getAsciiValue('A'));  // 65
        System.out.println(getAsciiValue('a'));  // 97
        System.out.println(getAsciiValue('Z'));  // 90
    }
}

Method 3: Streams API (Java 8+)

The streams API provides a functional approach to process entire strings. This is ideal for encoding messages or computing word values.

import java.util.stream.Collectors;

public class StreamsExample {

    // Convert an entire string to a dash-separated number sequence
    public static String encodeA1Z26(String text) {
        return text.toUpperCase()
            .chars()
            .filter(Character::isLetter)
            .map(c -> c - 'A' + 1)
            .mapToObj(Integer::toString)
            .collect(Collectors.joining("-"));
    }

    // Calculate the word value (sum of all letter positions)
    public static int wordValue(String text) {
        return text.toUpperCase()
            .chars()
            .filter(Character::isLetter)
            .map(c -> c - 'A' + 1)
            .sum();
    }

    // Decode a number sequence back to letters
    public static String decodeA1Z26(String encoded) {
        StringBuilder result = new StringBuilder();
        for (String part : encoded.split("-")) {
            int num = Integer.parseInt(part.trim());
            if (num >= 1 && num <= 26) {
                result.append((char) ('A' + num - 1));
            }
        }
        return result.toString();
    }

    public static void main(String[] args) {
        System.out.println(encodeA1Z26("Hello"));
        // Output: 8-5-12-12-15

        System.out.println(wordValue("JAVA"));
        // Output: 38 (10+1+22+1)

        System.out.println(decodeA1Z26("8-5-12-12-15"));
        // Output: HELLO
    }
}

The .chars() method returns an IntStream of Unicode code points. We filter for letters, subtract 'A' to get positions, and join the results. You can see the A1Z26 system in action on our A1Z26 cipher tool.

A1Z26 vs. ASCII: Two Numbering Systems

When people say "convert letters to numbers," they usually mean one of two systems:

SystemAMZJava Code
A1Z26 (Position)11326c - 'A' + 1
ASCII (Uppercase)657790(int) c
ASCII (Lowercase)97109122(int) c

The A1Z26 system is used in ciphers, puzzles, and numerology. ASCII values are used in programming, data transmission, and text encoding. Both are just different offsets of the same underlying character data.

Preserving Word Boundaries

For multi-word messages, you often want to keep word structure intact. Here is a method that uses "/" as a word separator:

public static String encodeWithWords(String text) {
    StringBuilder result = new StringBuilder();
    String[] words = text.split("\\s+");

    for (int w = 0; w < words.length; w++) {
        if (w > 0) result.append(" / ");
        String word = words[w].toUpperCase();
        boolean first = true;
        for (char c : word.toCharArray()) {
            if (Character.isLetter(c)) {
                if (!first) result.append("-");
                result.append(c - 'A' + 1);
                first = false;
            }
        }
    }
    return result.toString();
}

// encodeWithWords("Hello World")
// Output: "8-5-12-12-15 / 23-15-18-12-4"

Complete Conversion Utility Class

Here is a production-ready utility class that handles all conversion directions:

public final class AlphabetConverter {

    private AlphabetConverter() {} // Prevent instantiation

    /** Letter to A1Z26 position (1-26), or -1 if not a letter */
    public static int toPosition(char c) {
        if (Character.isLetter(c)) {
            return Character.toUpperCase(c) - 'A' + 1;
        }
        return -1;
    }

    /** Position (1-26) to uppercase letter */
    public static char toLetter(int position) {
        if (position < 1 || position > 26) {
            throw new IllegalArgumentException(
                "Position must be 1-26, got: " + position);
        }
        return (char) ('A' + position - 1);
    }

    /** Encode a string as A1Z26 with configurable separator */
    public static String encode(String text, String sep) {
        return text.toUpperCase().chars()
            .filter(Character::isLetter)
            .map(c -> c - 'A' + 1)
            .mapToObj(Integer::toString)
            .collect(Collectors.joining(sep));
    }

    /** Decode A1Z26 string back to text */
    public static String decode(String encoded, String sep) {
        StringBuilder sb = new StringBuilder();
        for (String token : encoded.split(sep)) {
            String trimmed = token.trim();
            if (trimmed.equals("/")) {
                sb.append(' ');
            } else {
                try {
                    int n = Integer.parseInt(trimmed);
                    if (n >= 1 && n <= 26) {
                        sb.append(toLetter(n));
                    }
                } catch (NumberFormatException ignored) {}
            }
        }
        return sb.toString();
    }

    /** Calculate word value */
    public static int wordValue(String text) {
        return text.toUpperCase().chars()
            .filter(Character::isLetter)
            .map(c -> c - 'A' + 1)
            .sum();
    }
}

Unit Testing Your Conversion Code

Always test edge cases. Here are JUnit 5 tests covering the critical scenarios:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class AlphabetConverterTest {

    @Test
    void testLetterToPosition() {
        assertEquals(1, AlphabetConverter.toPosition('A'));
        assertEquals(26, AlphabetConverter.toPosition('Z'));
        assertEquals(13, AlphabetConverter.toPosition('m')); // lowercase
        assertEquals(-1, AlphabetConverter.toPosition('5')); // not a letter
        assertEquals(-1, AlphabetConverter.toPosition(' ')); // space
    }

    @Test
    void testPositionToLetter() {
        assertEquals('A', AlphabetConverter.toLetter(1));
        assertEquals('Z', AlphabetConverter.toLetter(26));
        assertEquals('M', AlphabetConverter.toLetter(13));
    }

    @Test
    void testInvalidPositionThrows() {
        assertThrows(IllegalArgumentException.class,
            () -> AlphabetConverter.toLetter(0));
        assertThrows(IllegalArgumentException.class,
            () -> AlphabetConverter.toLetter(27));
    }

    @Test
    void testEncodeString() {
        assertEquals("8-5-12-12-15",
            AlphabetConverter.encode("Hello", "-"));
        assertEquals("10,1,22,1",
            AlphabetConverter.encode("Java", ","));
    }

    @Test
    void testWordValue() {
        assertEquals(38, AlphabetConverter.wordValue("JAVA"));
        assertEquals(52, AlphabetConverter.wordValue("Hello"));
    }

    @Test
    void testRoundTrip() {
        String original = "HELLO";
        String encoded = AlphabetConverter.encode(original, "-");
        String decoded = AlphabetConverter.decode(encoded, "-");
        assertEquals(original, decoded);
    }
}

Performance Considerations

  • char arithmetic is O(1). Each conversion is a single subtraction, making it extremely fast even in tight loops.
  • Streams have overhead. For single characters, use direct arithmetic. Reserve streams for processing entire strings or collections.
  • StringBuilder beats String concatenation. In loops, always use StringBuilder rather than += on Strings. Java creates a new String object for every concatenation.
  • Pre-built lookup arrays are fastest for repeated conversions: char[] LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();

Try it yourself: Our ASCII Converter lets you see ASCII values for any text instantly. No Java installation needed.

Try it now →

Frequently Asked Questions

How do I convert a letter to a number in Java?

Use char arithmetic: Character.toUpperCase(letter) - 'A' + 1. This maps A to 1, B to 2, through Z to 26. Java chars are numeric types, so subtraction works directly. For ASCII values instead, simply cast to int: (int) letter.

What is the difference between A1Z26 and ASCII numbering in Java?

A1Z26 numbers letters 1-26, while ASCII assigns 65-90 (uppercase) and 97-122 (lowercase). The relationship is simple: A1Z26 position = ASCII value - 64 for uppercase. Both systems use the same underlying char data; they just apply different offsets.

How do I convert a string to an array of numbers in Java?

Use Java streams: text.toUpperCase().chars().filter(Character::isLetter).map(c -> c - 'A' + 1).toArray(). This filters non-letter characters and returns an int[] of alphabet positions. For older Java versions, use a for-each loop with toCharArray().

Can I convert numbers back to letters in Java?

Yes, use (char)('A' + number - 1) for uppercase or (char)('a' + number - 1) for lowercase. Always validate that the number is between 1 and 26 first. For example, (char)('A' + 13 - 1)returns 'N'.

Related Articles