Maximální délka řetězce java. Otázka: Maximální délka řetězce v Javě je metoda length(). Struktura záhlaví objektu

Popis hlavních metod datového typu String.
Java používá pro práci s řetězci datový typ String.
Inicializace
Tento datový typ je inicializován stejně jako ostatní primitivní typy.
řetězec a;
Vytvoří nový objekt zadejte řetězec s výchozí hodnotou null.
tým
a = "Řetězec";
Zapíše slovo String do proměnné a.
Řetězec a znak
Řetězec v Javě si lze představit jako pole znaků. typ char. Proto má Java jednoduchými způsoby získání jakýchkoli znaků z řetězce. Nechť existuje proměnná b typu char.
tým
int I = a.indexOf(b);
Zapíše do I číslo prvního výskytu znaku b v nalezeném řetězci. Pozor, číslování znaků nezačíná od 1, ale od 0, takže pokud je ve výše uvedeném příkladu znak b roven písmenu C, pak se do proměnné I zapíše hodnota 0. Pokud hledaný znak nebude se objeví v řetězci, proměnná I bude zapsána zapsaná hodnota je -1.

Operátor lastIndexOf funguje na stejném principu, ale vrací číslo posledního výskytu znaku v řetězci.

Nechť je int i.
tým
char c = a.charAt(i);
Zapíše do proměnné c symbol stojící u i-té místo v řadě a. Ani zde nezapomeňte na funkce číslování v Javě. Pokud je délka řetězce menší než hodnota i, bude program považovat takový pokus o přístup za chybu.
Délku řetězce (počet znaků v něm) můžete získat následovně:
tým
Int I = a.length();
Zapíše délku řetězce a do proměnné I.

Můžete také nahradit všechny výskyty znaku v řetězci jiným znakem. Mějme řetězec a2 a potřebujeme nahradit všechny znaky b1 znakem b2 a výsledek zapsat do řetězce a1. To se provádí pomocí následujícího příkazu:

a1 = a2.nahradit(b1, b2);
Stojí za zmínku, že pokud potřebujete nahradit všechny prvky v původním řetězci, aniž byste vytvořili nový, můžete psát
a1 = a1.nahradit(b1, b2);
V Javě je také lehká cesta přeložit všechny znaky v řetězci z malá písmena na vrchol a naopak.
tým
a = a.toLowerCase();
Nahradí všechna velká písmena malými písmeny. Pokud například použijeme tento operátor na řetězec z prvního příkladu, výstupem bude slovo „řetězec“.

Operátor toUpperCase dělá opak, to znamená, že v případě výše uvedeného příkladu se hodnota řetězce a stane „STRING“.

Práce se strunami
Můžeme také vzájemně sčítat řetězce, porovnávat je a získat podřetězec daného řetězce.

Řetězce můžete přidávat stejně jako jiné primitivní datové typy. Nechť existují řetězce a1 a a2 a jejich hodnoty jsou „Str“ a „oka“.

tým
a = al + a2;
Napíše slovo „String“ do řádku a1, což je „součet“ řádků a1 a a2. Stejný výsledek bude získán pomocí příkazu
a = a1.concat(a2);
tým
Int I = a1.compareTo(a2);
Zapíše do proměnné I hodnotu menší než nula, pokud je řetězec a1 lexikograficky menší než řetězec a2, a v opačném případě vrátí hodnotu větší než nula. Pokud je a1 lexikograficky ekvivalentní a2, pak se do I zapíše hodnota 0.
Nechť existuje řetězec a a číslo i.
tým
Řetězec a1 = a.podřetězec(i);
Zapíše do řetězce a1 celou část řetězce a, která začíná znakem číslo i. Můžete také ustřihnout podřetězec na druhé straně. Mějme také číslo j.
V tomto případě příkaz
Řetězec a1 = a.substring(i, j);
Zapíše do řetězce a1 část řetězce a začínající číslem znaku I až po znak číslo j (bez tohoto znaku samotného).

Což se rovná 2^31 - 1 (nebo asi 2 miliardám.)

Pokud jde o délku a indexování polí (jako je char , což je pravděpodobně způsob, jak reprezentovat interní data pro String s), kapitola 10: Pole The Java Language Specification, Java SE 7 Edition uvádí následující:

Proměnné obsažené v poli nemají jména; místo toho odkazují na výrazy přístupu k poli, které používají nezáporný celočíselný index hodnoty. Tyto proměnné se nazývají komponenty pole. Pokud má pole n složek, říkáme, že n je délka pole; Na komponenty pole se odkazuje pomocí celočíselných indexů od 0 do n - 1 včetně.

Kromě toho musí mít indexování hodnoty int, jak je uvedeno v části 10.4:

Pole musí být indexována hodnotami int;

Proto se ukazuje, že limit je skutečně 2^31 - 1, protože toto je maximální hodnota Pro nezáporná hodnota int .

Pravděpodobně však existují další omezení jako např maximální velikost přidělené pole.

Návratový typ metody length() třídy String int.

Takže maximální hodnota int 2147483647 .

Řetězec je považován za vnitřní pole znaků, takže indexování se provádí v maximálním rozsahu. To znamená, že nemůžeme indexovat 2147483648. člena. Maximální délka řetězce v Javě je tedy 2147483647.

Primitivní typ data int- 4 bajty (32 bitů) v jazyce Java. Znaménkový bit je 1 bit (MSB). Rozsah je omezen na -2^31 až 2^31-1 (-2147483648 až 2147483647). Pro indexování nemůžeme použít záporné hodnoty. Rozsah, který můžeme použít, je samozřejmě 0 až 2147483647.

Mám iMac z roku 2010 s 8GB RAM se systémem Eclipse Neon.2 Release (4.6.2) s Javou 1.8.0_25. S argumentem VM -Xmx6g jsem spustil následující kód:

StringBuilder sb = new StringBuilder(); for (int i = 0; i< Integer.MAX_VALUE; i++) { try { sb.append("a"); } catch (Throwable e) { System.out.println(i); break; } } System.out.println(sb.toString().length());

Tisky:

Požadovaná velikost pole překračuje limit VM 1207959550

Zdá se tedy, že maximální velikost pole je ~1207 959 549. Pak jsem si uvědomil, že nás ve skutečnosti nezajímá nedostatek paměti v Javě: jen hledáme maximální velikost pole (která se zdá být definována jako konstanta). Tak:

Pro (int i = 0; i< 1_000; i++) { try { char array = new char; Arrays.fill(array, "a"); String string = new String(array); System.out.println(string.length()); } catch (Throwable e) { System.out.println(e.getMessage()); System.out.println("Last: " + (Integer.MAX_VALUE - i)); System.out.println("Last: " + i); } }

Co tiskne:

Požadovaná velikost pole překračuje limit VM Poslední: 2147483647 Poslední: 0 Požadovaná velikost pole překračuje limit VM Poslední: 2147483646 Poslední: 1 Prostor haldy Java Poslední: 2147483645 Poslední: 2

Zdá se tedy, že maximum je Integer.MAX_VALUE – 2 nebo (2^31) – 3

P.S. Nejsem si jistý, proč můj StringBuilder dosáhl maxima na 1207959550 a můj znak překročil značku (2^31)-3. Zdá se, že AbstractStringBuilder zdvojnásobuje velikost svého interního znaku, aby byl větší, což pravděpodobně způsobuje problém.

8 odpovědí

Dovolte mi nejprve zdůraznit tři různé způsoby k podobnému účelu.

délka - pole(int , double , String) - znát délku polí

délka() - Objekt související s řetězcem(String, StringBuilder atd.) - znát délku řetězce

velikost () - Sbírkový předmět(ArrayList, Set atd.) - znát velikost kolekce

Nyní zapomeňte na length(), zvažte pouze length a size() .

délka není metoda, takže je logické, že nebude fungovat na objektech. Funguje pouze na polích.
size() jeho název to vystihuje lépe a jelikož se jedná o metodu, bude použita v případě těch objektů, které pracují s kolekcí (collection frameworks), jak jsem tam uvedl.

Nyní přejděte na délka():
Řetězec není primitivní pole (nemůžeme tedy použít .length), ani to není kolekce (nemůžeme tedy použít .size()), takže potřebujeme také další, což je length() (ponechat rozdíly a slouží účelu).

Jako odpověď na Proč?
Považuji to za užitečné, snadno zapamatovatelné a použitelné a přátelské.

Trochu zjednodušeně si to můžete představit jako pole, která jsou zvláštní příležitost, spíše než běžné třídy (trochu jako primitiva, ale ne). String a všechny kolekce jsou třídy, takže metody pro získání velikosti, délky nebo podobných věcí.

Hádám, že důvodem v době vývoje byl výkon, pokud to vytvořili dnes, pravděpodobně přišli s něčím jako pole založená na poli.

Pokud má někdo zájem, zde je malý úryvek kódu ilustrující rozdíl mezi těmito dvěma ve vygenerovaném kódu, nejprve zdroj:

Veřejná třída LengthTest ( public static prázdný hlavní(argumenty řetězce) ( int pole = (12,1,4); řetězec řetězce = "Hoo"; System.out.println(délka pole); System.out.println(string.length()); ) )

Vyjmutím ne tak důležité části bajtového kódu spuštěním javap -c na třídě se zobrazí následující dva řádky:

20: getstatic #3; //Pole java/lang/System.out:Ljava/io/PrintStream; 23: aload_1 24: délka pole 25: invokevirtual #4; //Metoda java/io/PrintStream.println:(I)V 28: getstatic #3; //Pole java/lang/System.out:Ljava/io/PrintStream; 31: aload_2 32: invokevirtual #5; //Metoda java/lang/String.length:()I 35: invokevirtual #4; //Metoda java/io/PrintStream.println:(I)V

V prvním případě (20-25) se kód jednoduše zeptá JVM na velikost pole (v JNI by to bylo volání GetArrayLength()), zatímco v případě String (28-35) potřebuje zavolat způsob, jak získat délku.

V polovině 90. let by bez dobrých JIT atd. zcela zabilo výkon mít pouze java.util.Vector (nebo něco podobného) a ne jazykovou konstrukci, která se ve skutečnosti nechovala jako třída, ale byla rychlá. Samozřejmě by mohli zamaskovat vlastnost jako volání metody a zpracovat ji v kompilátoru, ale myslím, že by bylo ještě více matoucí mít metodu na něčem, co není skutečná třída.

Int myArray = new int; String myString = "ahoj světe!"; Seznam myList = nový ArrayList (); myArray.length //udává délku pole myString.length() //udává délku řetězce myList.size() //udává délku seznamu

S největší pravděpodobností byly řetězce a pole navrženy v jiný čas a proto byly používány v různých konvencích. Jedním z důvodů je, že protože řetězce používají interní pole, byla použita metoda length(), aby se zabránilo duplikování stejných informací. Další je, že použití metody length() pomáhá zdůraznit neměnnost řetězců, i když je neměnná také velikost pole.

Nakonec je to jen nekonzistentní, co se vyvinulo, což by se určitě napravilo, kdyby byl jazyk od základu přepracován. Pokud vím, žádné jiné jazyky (C#, python, scala atd.) nedělají totéž, takže je to s největší pravděpodobností malá chyba, která je součástí jazyka.

Pokud stejně použijete nesprávný, dostanete chybu :P:D

V Java pole ukládá svou délku odděleně od struktury, ve které jsou data skutečně uložena. Když vytváříte pole, zadáte jeho délku a to se stane definujícím atributem pole. Bez ohledu na to, co uděláte s polem délky N (změňte hodnoty, nulové hodnoty atd.), bude to vždy pole délky N.

Délka řetězce je náhodná; Není to atribut String, ale vedlejší produkt. Ačkoli jsou řetězce Java ve skutečnosti neměnné, pokud byste mohli změnit jejich obsah, mohli byste změnit jejich délku. Vypuštěním posledního znaku (pokud by to bylo možné) by se zkrátila délka.

Uvědomuji si, že je to dobrý rozdíl, a mohu ho odsuzovat, ale je to tak. Pokud vytvořím pole délky 4, tato délka 4 je definující charakteristikou pole a platí bez ohledu na to, co je uvnitř. Pokud vytvořím řetězec obsahující "psi", tento řetězec je dlouhý 4, protože obsahuje čtyři znaky.

Vidím to jako ospravedlnění toho, že jeden děláte s atributem a druhý s metodou. Po pravdě je to možná neúmyslná nesrovnalost, ale vždycky mi to dávalo smysl a vždycky jsem o tom takhle přemýšlel.

Naučil jsem se, že u polí není délka metodou načtena kvůli následujícímu strachu: programátoři jednoduše přiřadili délku místní proměnné před vstupem do smyčky (přemýšlejte o pro smyčku, kde podmínka používá délku pole.) Programátor by to pravděpodobně udělal, aby ořízl volání funkcí (a tím zvýšil výkon). Problém je v tom, že délka se může během smyčky změnit, ale proměnná ne.

Při každém vytvoření pole je určena jeho velikost. Délku lze tedy považovat za designový atribut. Pro String je to v podstatě pole znaků. Délka je vlastnost pole znaků. Není třeba uvádět délku jako pole, protože ne vše potřebuje toto pole. http://www.programcreek.com/2013/11/start-from-length-length-in-java/

V tom souhlasím s Fredrikem Nejlepší volba pro optimalizátor kompilátoru. To také vyřeší problém: i když použijete vlastnost pro pole, nevyřešili jste problém pro řetězce a další (neměnné) typy kolekcí, protože například řetězec je založen na pole znaků jak můžete vidět v definici třídy string:

Veřejná finální třída String implementuje java.io.Serializable, Comparable , CharSequence ( soukromá konečná hodnota znaku; // ...

A nesouhlasím s tím, že to bude ještě více matoucí, protože pole dědí všechny metody z java.lang.Object .

Jako inženýrovi se mi opravdu nelíbí odpověď "Protože to tak bylo vždycky." a přál si lepší odpověď. Ale v tomto případě je to podobné.

Podle mého názoru je to chyba designu v Javě a neměla by být implementována tímto způsobem.

Známý jávským způsobem porovnávání řetězců je lexikografická metoda implementovaná v metodě CompareTo() třídy String. Někdy je ale potřeba porovnat struny na základě jejich délky. Ve výchozím nastavení k tomu nemůžete použít metodu CompareTo(). Místo toho musíte napsat vlastní metodu, která vypočítá délku řetězců pomocí metody length() a porovná je. Taková metoda musí vrátit kladnou hodnotu, pokud je první řetězec delší než druhý; negativní význam, pokud je délka prvního řetězce menší než délka druhého a nula, pokud mají oba řetězce stejnou délku.

Takovou jednorázovou metodu můžete definovat pomocí anonymní vnitřní třídy a pak ji použít k seřazení seznamu řetězců podle délky. Tato metoda funguje dobře v Javě 6 a 7, ale v Javě 8 funguje ještě lépe díky menšímu šumu díky nová vlastnost tzv. lambda výrazy.

Zde je návod, jak to udělat ve více dřívější verze Jáva:

public int Compare(String s1, String s2) ( return s1.length() - s2.length(); )

Srovnání délky seznam polí řádků v Javě 8 to lze ještě zjednodušit použitím výrazu lambda a nových výchozích metod přidaných do třídy java.util.Comparator:

Komparátor strlenComp = (a, b) -> Integer.compare(a.length(), b.length());

aab jsou dva objekty typu String. Integer.compare() je nová metoda přidáno v Javě 8. Protože pro řetězce používáme komparátor, je kompilátor schopen odvodit typy a a b , což jsou String .

Níže je uveden příklad použití tohoto komparátoru délky řetězců k seřazení seznamu řetězců na základě jejich délky. V tomto příkladu jsme demonstrovali programy JDK 6 a 7 pomocí anonymní třídy a nová cesta pomocí lambda výrazů, které jsou dostupné v Javě 8. Zabere pouze jeden řádek a je mnohem snazší jej pochopit, pokud znáte syntaxi výrazu lambda.

Jak seřadit seznam řetězců podle jejich délky v Javě 7 a 8

Java 6, 7

Importovat java.util.ArrayList; Importovat java.util.Arrays; Import java.util.Collections; Importovat java.util.Comparator; Importovat java.util.List; / * * Java program seřadit seznam řetězců podle jejich délky * / public class StringComparisonByLength( Public static void main (String args) ( List knihy = nový ArrayList<>(Arrays.asList("Efektivní Java", "Algoritmy", "Refaktoring")); System.out.println("Řazení seznamu řetězců podle délky v JDK 7 ======"); System.out.println("Původní seznam bez řazení"); System.out.println(knihy); Komparátor byLength = nový komparátor ()( @Override Public int srovnání (String s1, String s2) ( Return s1.length () - s2.length (); ) ); Collections.sort(knihy, podleLength); System.out.println("Stejný seznam po seřazení řetězce podle délky"); System.out.println(knihy); ))

Výsledek

Řazení seznamu řetězců podle délky v JDK 7 ====== Původní seznam bez řazení Stejný seznam po řazení řetězce podle délky

Java 8

Importovat java.util.ArrayList; Importovat java.util.Arrays; Importovat java.util.Comparator; Importovat java.util.List; / * * Java program pro seřazení seznamu řetězců podle délky v JDK 8 * / public class SortingListOfStringByLength( public static void main(String args) ( // V Java 8 System.out.println("Třídění seznamu řetězců podle délky v Java 8 ======"); Seznam města = nový ArrayList<>(Arrays.asList("Londýn", "Tokio", "NewYork")); System.out.println("Původní seznam bez řazení"); System.out.println(města); cities.sort((první, druhý) -> Integer.compare(first.length(), second.length())); System.out.println("Stejný seznam po seřazení řetězce podle délky"); System.out.println(města); ))

Výsledek

Řazení seznamu řetězců podle délky v Javě 8 ====== Původní seznam bez řazení Stejný seznam po řazení řetězce podle délky

To je vše o porovnání délky řetězců Java a řazení seznamu řetězců podle délky v Javě 7 a Javě 8. V Nejnovější verze jazyk, je to mnohem pohodlnější, protože můžete vytvořit vlastní komparátor pouze s jedním řádkem pomocí výrazu lambda. JDK 8 API obsahuje mnoho podobné metody, které umožňují ještě složitější srovnání. Například pomocí metody thenComparing() můžete zřetězit více komparátorů.

Překlad článku " Jak porovnat String podle jejich délky v Java 7 a 8» přátelský projektový tým

V tomto tutoriálu se naučíme pracovat s řetězci v Javě. Řetězce, které jsou tak široce používány v programování, jsou posloupností znaků. V jazyce Java programovánířetězce jsou objekt. Platforma Java poskytuje třídu String pro vytváření a správu řetězců.

Vytváření řetězců

Nejjednodušší způsob, jak vytvořit řetězec, vypadá takto: String greeting = "Ahoj světe!" ; V v tomto případě « Ahoj světe!“ je řetězcový literál (tj. konstanta) skládající se z posloupnosti znaků uzavřených v uvozovkách. Kdykoli kompilátor narazí na řetězcový literál, vytvoří objekt typu String s hodnotou, v našem případě "Hello World!". Jako každý jiný objekt lze vytvořit řetězec pomocí klíčové slovo Nový. Řetězcová třída má tři konstruktory, které vám umožňují vytvořit objekt pomocí různé zdroje, například pole znaků. Vytiskne se poslední řádek příkladu Ahoj. Třída String je neměnná, takže jakmile vytvoříme objekt, nemůžeme jej změnit. Některé metody, na které se podíváme níže, to mohou vyřešit. Protože Řetězec je neměnný, tyto metody vytvářejí a vracejí nový řádek obsahující výsledek operace.

Délka struny

Metody pro získávání informací o řetězci se nazývají přístupové metody. Jednou z těchto metod je length() . Vrací počet znaků v řetězci. V následujícím příkladu bude len rovna 17: Proměnná palindrom obsahuje palindrom, tzn. slovo nebo věta, která se čte oběma způsoby stejně. Pojďme psát malý program, který obrátí palindrom. Použijeme metodu charAt(i), která vrací i znak řetězce, počínaje 0. Program vypíše doT saw I was toD Abychom řetězec obrátili, nejprve jsme z řetězce vytvořili pole znaků (první smyčka), poté vytvořili nové pole, do kterého napsal invertované první pole a poté vytvořil nový řetězec . Třída String obsahuje metodu getChars(), která vrací pole znaků, takže první smyčku lze nahradit řetězcem: palindrom. getChars(0, délka, tempCharArray, 0);

Zřetězení řetězců

Třída String implementuje metodu pro zřetězení dvou řetězců: string1. concat(řetězec2); Tento kód vrátí nový řetězec obsahující řetězec1 a řetězec2, které jsou k němu připojeny. Můžete také použít tato metoda s řetězcovými literály: "Jmenuji se " . concat("Rumplestiltskin"); Řetězce se nejčastěji spojují pomocí operátoru „ + “, například: „Ahoj,“ + „svět“ + „!“. Výsledkem bude řetězec " Ahoj světe!" Operátor "+" se široce používá k zobrazení informací, například: String string1 = "saw I was" ; Systém. ven. println ("Tečka " + řetězec1 + "Tod" ) ; Kód vypíše " Dot viděla, že jsem Tod" Takové zřetězení lze použít ve spojení s jakýmikoli jinými objekty. U objektů, které nejsou řetězce, bude zavolána metoda toString(), která je převede na řetězce. Nastavte výstupní formát řetězce Už jsme se podívali na metody printf() a format() při formátování výstupu čísel. Třída String má podobnou metodu, která vrací řetězec. Použitím statická metoda format() můžete vytvořit šablonu akcií, kterou lze znovu použít, například místo toho: Můžete použít tento kód: To je ono! :) Odkaz na první


Horní