String.codePointAt în Java

Lucrează cu puncte de cod Unicode întregi (inclusiv emoji), nu cu valori char: citire, numărare, deplasare.

Sintaxă
int codePointAt(int index)
int codePointBefore(int index)
int codePointCount(int beginIndex, int endIndex)
int offsetByCodePoints(int index, int codePointOffset)

Ce face String.codePointAt

În Java, un String este stocat ca UTF-16: majoritatea caracterelor (inclusiv ă, î, ș, ț) ocupă un char, dar emoji-urile și unele simboluri ocupă două (o „pereche surogat”). Metodele de aici lucrează cu puncte de cod, adică cu caracterul Unicode complet.

codePointAt(i) returnează punctul de cod care începe la indicele i; codePointBefore(i) pe cel care se termină chiar înainte de i. codePointCount(început, sfârșit) numără caracterele reale dintr-o porțiune; codePointCount(0, s.length()) este lungimea „adevărată” a textului.

offsetByCodePoints(i, n) returnează indicele char la care ajungi dacă pornești de la i și sari peste n puncte de cod. Te ajută să tai un șir fără să rupi un emoji în două.

Parametri

Parametru Descriere
index Indice char (de la 0 la length()).
beginIndex, endIndex Porțiunea numărată de codePointCount (sfârșitul exclusiv).
codePointOffset Câte puncte de cod sari (poate fi negativ).

Ce returnează

codePointAt/codePointBefore: codul Unicode (int). codePointCount: numărul de puncte de cod. offsetByCodePoints: un indice char.

Exemple

Exemplul 1: Lungimea reală a unui mesaj cu emoji

public class Main {
    public static void main(String[] args) {
        String mesaj = "La mulți ani! 🎂🎉";
        System.out.println("length(): " + mesaj.length());
        System.out.println("caractere reale: " + mesaj.codePointCount(0, mesaj.length()));
    }
}

Rezultat

length(): 18
caractere reale: 16

Exemplul 2: Codul Unicode al unor caractere

Integer.toHexString afișează codul în forma obișnuită U+….

public class Main {
    public static void main(String[] args) {
        String text = "ș😀a";
        System.out.println("ș = U+" + Integer.toHexString(text.codePointAt(0)).toUpperCase());
        System.out.println("😀 = U+" + Integer.toHexString(text.codePointAt(1)).toUpperCase());
        System.out.println("charAt(2) este jumătatea a doua: " + (int) text.charAt(2));
        System.out.println("înainte de 'a': U+" + Integer.toHexString(text.codePointBefore(4)).toUpperCase());
    }
}

Rezultat

ș = U+219
😀 = U+1F600
charAt(2) este jumătatea a doua: 56832
înainte de 'a': U+61

Exemplul 3: Primele n caractere, fără să rupi un emoji

substring(0, 5) ar tăia emoji-ul în două; offsetByCodePoints găsește indicele corect.

public class Main {
    static String primele(String s, int n) {
        int total = s.codePointCount(0, s.length());
        if (n >= total) {
            return s;
        }
        return s.substring(0, s.offsetByCodePoints(0, n));
    }

    public static void main(String[] args) {
        String status = "Ana😀 merge la Iași";
        System.out.println(primele(status, 4));
        System.out.println(primele(status, 5));
        System.out.println(status.offsetByCodePoints(0, 5));
    }
}

Rezultat

Ana😀
Ana😀 
6

Greșeli frecvente

  • Numeri caracterele cu length() pentru o limită de lungime (ex. un SMS). Emoji-urile se numără dublu; folosește codePointCount.
  • Apelezi codePointAt pe a doua jumătate a unei perechi surogat: primești doar jumătatea, nu emoji-ul. Avansează cu Character.charCount(cp) sau folosește codePoints().

Comenzi înrudite

  • String.chars: Returnează caracterele șirului ca IntStream (coduri numerice), ca să le prelucrezi cu operații de stream.
  • String.length: length() dă numărul de caractere; isEmpty() verifică dacă șirul e gol, isBlank() dacă are doar spații.
  • String.substring: Returnează o bucată din șir: de la beginIndex (inclusiv) până la endIndex (exclusiv) sau până la final.
  • String.charAt: Returnează caracterul (char) de la poziția dată; prima poziție este 0, ultima este length() – 1.