1. StringTokenizersınıf

Ve şimdi dizelerle çalışmayı içeren birkaç yaygın senaryo daha. Bir dizeyi birkaç parçaya nasıl ayırırsınız? Bunu yapmanın birkaç yolu var.

split()yöntem

Bir dizeyi birden çok parçaya ayırmanın ilk yolu, yöntemi kullanmaktır split(). Özel bir sınırlayıcı dize tanımlayan bir normal ifade, bağımsız değişken olarak iletilmelidir. Normal ifadenin ne olduğunu Java Multithreading arayışında öğreneceksiniz .

Örnek:

kod Sonuç
String str = "Good news everyone!";
String[] strings = str.split("ne");
System.out.println(Arrays.toString(strings));
Sonuç, üç dizeden oluşan bir dizi olacaktır:
["Good ", "ws everyo", "!"]

Basit, ancak bazen bu yaklaşım aşırıdır. Çok sayıda sınırlayıcı varsa (örneğin, boşluklar, yeni satır karakterleri, sekmeler, noktalar), o zaman oldukça karmaşık bir normal ifade oluşturmanız gerekir. Okuması ve dolayısıyla değiştirmesi zordur.

StringTokenizersınıf

Java'nın tüm işi bir diziyi alt dizilere bölmek olan özel bir sınıfı vardır.

Bu sınıf normal ifadeler kullanmaz: bunun yerine, yalnızca sınırlayıcılardan oluşan bir dize iletirsiniz. Bu yaklaşımın avantajı, tüm diziyi bir kerede parçalara ayırmaması, bunun yerine her seferinde bir adım baştan sona hareket etmesidir.

Sınıfın bir yapıcısı ve iki önemli yöntemi vardır. Kurucuya, parçalara ayırdığımız bir diziyi ve sınırlayıcı karakterlerden oluşan bir diziyi iletiyoruz.

Yöntemler Tanım
String nextToken()
Bir sonraki alt dizeyi döndürür
boolean hasMoreTokens()
Daha fazla alt dizi olup olmadığını kontrol eder.

nextLine()Bu sınıf bir şekilde and yöntemlerine de sahip olan Scanner sınıfını anımsatıyor hashNextLine().

StringTokenizerBu komutla bir nesne oluşturabilirsiniz :

StringTokenizer name = new StringTokenizer(string, delimiters);

stringParçalara bölünecek dize nerede . Ve delimitersbir dizedir ve içindeki her karakter bir sınırlayıcı olarak değerlendirilir. Örnek:

kod Konsol çıkışı
String str = "Good news everyone!";

StringTokenizer tokenizer = new StringTokenizer(str,"ne");
while (tokenizer.hasMoreTokens())
{
   String token = tokenizer.nextToken();
   System.out.println(token);
}
Good 
ws 
v
ryo
!

Yapıcıya ikinci dize olarak iletilen dizedeki her karakterin StringTokenizerbir ayırıcı olarak kabul edildiğini unutmayın.



2. String.format()yöntem ve StringFormattersınıf

String sınıfının bir başka ilginç yöntemi de format().

Diyelim ki veri depolayan çeşitli değişkenleriniz var. Bunları ekranda tek satırda nasıl görüntülersiniz? Örneğin, bazı verilerimiz (sol sütun) ve istenen çıktımız (sağ sütun) var:

kod Konsol çıkışı
String name = "Amigo";
int age = 12;
String friend = "Diego";
int weight = 200;
User = {name: Amigo, age: 12 years, friend: Diego, weight: 200 kg.}

Kodunuz muhtemelen şuna benzer:

Program kodu
String name = "Amigo";
int age = 12;
String friend = "Diego";
int weight = 200;

System.out.println("User = {name: " + name + ", age:" + age + " years, friend: " + friend+", weight: " + weight + " kg.}");

Böyle bir kod çok okunabilir değil. Değişken adları daha uzun olsaydı, kod daha da zorlaşırdı:

Program kodu
class User {
    ......
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public List<String> getFriends() {
        return friends;
    }

    public ExtraInformation getExtraInformation() {
        return extraInformation;
    }
}

User user = new User();

System.out.println("User = {name: " + user.getName() + ", age:" + user.getAge() + " years, friend: " + user.getFriends().get(0) + ", weight: " + user.getExtraInformation().getWeight() + " kg.}");

Pek okunmuyor, değil mi?

Ancak bu, gerçek dünya programlarında sık görülen bir durumdur, bu yüzden size bu kodu daha basit ve daha özlü yazmanın bir yolunu anlatmak istiyorum.

String.format

String sınıfının statik bir format()yöntemi vardır: bir dizeyi verilerle birleştirmek için bir model belirlemenizi sağlar. Komutun genel görünümü aşağıdaki gibidir:

String name = String.format(pattern, parameters);

Örnek:

kod Sonuç
String.format("Age=%d, Name=%s", age, name);
Age=12, Name=Amigo
String.format("Width=%d, Height=%d", width, height);
Width=20, Height=10
String.format("Fullname=%s", name);
Fullname=Diego

Yöntemin ilk parametresi , veri eklemeniz gereken yerlerde, istenen tüm metni ve biçim belirticileri ( ve format()gibi) adı verilen özel karakterleri içeren bir biçim dizesidir .%d%s

Yöntem format(), bunları %sve %dbiçim belirticilerini, parametre listesindeki biçim dizesini izleyen parametrelerle değiştirir. Bir dize eklemek istiyorsak, yazarız %s. Bir sayı eklemek istiyorsak, biçim belirleyicisi %d. Örnek:

kod Sonuç
String s = String.format("a=%d, b=%d, c=%d", 1, 4, 3);
seşittir"a=1, b=4, c=3"

Biçim dizgisi içinde kullanılabilecek biçim belirticilerinin kısa bir listesi aşağıdadır:

belirleyici Anlam
%s
String
%d
tamsayı: byte, short, int,long
%f
gerçek sayı: float,double
%b
boolean
%c
char
%t
Date
%%
%karakter

Bu belirticiler veri tipini belirtir, ancak verilerin sırasını gösteren belirticiler de vardır. Numarasına göre bir argüman elde etmek için (numaralandırma birden başlar), " " yerine " " yazmanız gerekir . Örnek:%1$d%d

kod Sonuç
String s = String.format("a=%3$d, b=%2$d, c=%d", 11, 12, 13);
seşittir"a=13, b=12, c=11"

%3$d3. bağımsız değişkeni alır, %2$dikinci bağımsız değişkeni alır ve %dilk bağımsız değişkeni alır. %sve biçim belirticileri , veya %dgibi belirticilerden bağımsız olarak bağımsız değişkenlere atıfta bulunur.%3$d%2$s



3. Dizi Havuzu

StringPoolKodda bir dize sabit değeri olarak belirtilen her dize , program çalışırken adı verilen bir bellek alanında saklanır . StringPooldizeleri depolamak için özel bir dizidir. Amacı, dizi depolamayı optimize etmektir:

İlk olarak, kodda belirtilen dizelerin bir yerde saklanması gerekir, değil mi? Kod komutlardan oluşur, ancak veriler (özellikle büyük diziler) koddan ayrı olarak bellekte saklanmalıdır. Kodda yalnızca dize nesnelerine yapılan başvurular görünür.

İkinci olarak, tüm aynı dize hazır değerleri bellekte yalnızca bir kez saklanmalıdır. Ve işte böyle çalışır. Sınıf kodunuz Java makinesi tarafından yüklendiğinde, StringPoolzaten orada değillerse, tüm dize değişmezleri eklenir. Zaten oradalarsa, o zaman basitçe StringPool.

StringBuna göre, kodunuzdaki birkaç değişkene aynı sabit değeri atarsanız , bu değişkenler aynı referansı içerecektir. Yalnızca bir kez bir hazır bilgi eklenecektir StringPool. Diğer tüm durumlarda, kod zaten StringPool.

İşte kabaca nasıl çalıştığı:

kod StringPool ile çalışmak
String a = "Hello";
String b = "Hello";
String c = "Bye";
String[] pool = {"Hello", "Bye"};
a = pool[0];
b = pool[0];
c = pool[1];

Bu nedenle ave bdeğişkenleri aynı referansları saklayacaktır.

intern()yöntem

Ve en iyi yanı, programlı olarak herhangi bir dizeyi ekleyebilirsiniz StringPool. StringBunu yapmak için değişkenin yöntemini çağırmanız yeterlidir intern().

Yöntem , dizeyi zaten orada değilse ekleyecek intern()ve .StringPoolStringPool

StringPoolYöntemi kullanarak iki özdeş dize eklenirse intern(), yöntem aynı referansı döndürür. Bu, dizeleri referansa göre karşılaştırmak için kullanılabilir. Örnek:

kod Not
String a = new String("Hello");
String b = new String("Hello");
System.out.println(a == b);


false
String a = new String("Hello");
String b = new String("Hello");

String t1 = a.intern();
String t2 = b.intern();
System.out.println(a == b);
System.out.println(t1 == t2);





false
true

Bu yöntemi pek sık kullanamazsınız, ancak insanlar röportajlarda bunun hakkında soru sormayı sever . Bu yüzden bilmek, bilmemekten daha iyidir.