28 Ağustos 2020 Cuma

StringBuilder Sınıfı

Giriş
Şu satırı dahil ederiz.
import java.lang.StringBuilder;
Açıklaması şöyle
StringBuilder is not thread-safe and an instance can be shared across multiple threads
Bu sınıfın kardeşi olan StringBuffer sınıfı thread safe'tir.

constructor
Şöyle yaparız.
StringBuilder sb = new StringBuilder ();
constructor - CharSequence
Metodun içi şöyle.
public StringBuilder(String str) {
  super(str.length() + 16);
   append(str);
}
constructor - String
Metodun içi şöyle.
public StringBuilder(String str) {
  super(str.length() + 16);
  append(str);
}
Örnek
Şöyle yaparız.
String str = "...";

StringBuilder sb = new StringBuilder (str);
append metodu - CharSequence
Örnek
Java 8 Stream'leri ile şöyle kullanılır.
StringBuilder sb = 
    p.stream()
     .filter( p -> p.lastName.equals("kent"))
     .map(p -> p.lastName)
     .collect(StringBuilder::new,
              StringBuilder::append,
              StringBuilder::append);
Örnek
Şöyle yaparız
StringBuilder sb =list.stream().parallel()
  .collect(
    StringBuilder::new, 
    StringBuilder::append, 
    StringBuilder::append
  )
);
appendCodePoint metodu - int
Şöyle yaparız. String.chars() int dizisi döndürür.
public static String removeDuplicateLetters(String s) {
    return s.chars().sorted().distinct().collect(
        StringBuilder::new,
        StringBuilder::appendCodePoint,
        StringBuilder::append
    ).toString();
}
capacity metodu
Şöyle yaparız
StringBuilder sb = new StringBuilder();
System.out.println(sb.capacity());
ensureCapacity metodu
Açıklaması şöyle
Ensures that the capacity is at least equal to the specified minimum. If the current capacity is less than the argument, then a new internal array is allocated with greater capacity. The new capacity is the larger of:
  • The minimumCapacity argument.
  • Twice the old capacity, plus 2.
If the minimumCapacity argument is nonpositive, this method takes no action and simply returns.
equals metodu
Bu sınıf equals metodunu override etmez. Şu kod false döner.
StringBuilder sb1 = new StringBuilder("string");
StringBuilder sb2 = new StringBuilder("string");

System.out.println(sb1.equals(sb2));
indexOf metodu
Şöyle yaparız.
int index = sb.indexOf ("kent");
length metodu
Şöyle yaparız
StringBuilder sb = new StringBuilder();
System.out.println(sb.length());
repeat metodu
Java 21 ile geliyor. İmzası şöyle
StringBuilder repeat(CharSequence cs,
                    int count)
StringBuilder repeat(int codePoint,
                     int count)
Örnek
Şöyle yaparız
var santaBuilder = new StringBuilder();
santaBuilder.repeat("Ho! ", 3);

var str = santaBuilder.toString()
// => "Ho! Ho! Ho! "
replace metodu
Şöyle yaparız.
int index = ...;
sb.replace (index, index + 2, ":");
reverse metodu
Şöyle yaparız.
StringBuilder reversedSb = sb.reverse ();
toString metodu
Metodun içi şöyle.
public String toString() {
  // Create a copy, don't share the array
  return new String(value, 0, count);
}
Şöyle yaparız.
String str = sb.toString()


Try With Resources

Giriş
try-with-resources kullanımıyla finally yazmaya gerek kalmıyor. Aslında finally bazen kafa karıştırıcı olabilir.

Bu konuyu açıklayan bazı yazılar yanlış anlamaya sebep oluyor. Sanki close içinde exception fırlatılırsa finally block içinden dışarıya sızabilir gibi anlaşılıyor.

Öyle olmadığını bu yazıda göstermeye çalıştım

1. Kullanım
Örnek
Kapatılmasını istediğimiz her kaynak bir değişkene atanmak zorundadır. Şöyle yaparız
try (Connection connection = DriverManager.getConnection(...);
     Statement statement = connection.createStatement();
     ResultSet resultSet = statement.executeQuery(sql)) {
    // ...   
}
Bazen kapatılan kaynak kendisine constructor içinde verilen kaynağı da kapatır. Bu durumda şöyle yapabiliriz
try (BufferedWriter bw = new BufferedWriter(new FileWriter(...)) {
    // ...   
}
Üretilen Kod
Örnek
Elimizde şöyle bir kod olsun
class MyBufferedReader extends BufferedReader {
  public MyBufferedReader(Reader in, int sz) {
    super(in, sz);
  }

  @Override
  public void close() throws IOException {
    super.close();
    throw new IOException("test");
  }
}

private void readFromMyBufferedReader() {
  Reader reader = new StringReader("test");
  try (MyBufferedReader myBufferedReader = new MyBufferedReader(reader, 1024)) {
    int read = myBufferedReader.read();
  } catch (IOException exception) {
    // Prints test
    log.error("Exception", exception);
  }
}
Üretilen kod şöyle
private void readFromMyBufferedReader() {
  Reader reader = new StringReader("test");

  try {
    MyBufferedReader bufferedReader = new MyBufferedReader(reader, 1024);

    try {
      int readValue = bufferedReader.read();
    } catch (Throwable readException) { // Üretilen kod
      try {
        bufferedReader.close();
      } catch (Throwable closeException) {
        readException.addSuppressed(closeException);
      }

      throw readException;
    }

      bufferedReader.close(); // Üretilen close() çağrısı
  } catch (IOException ioException) {
    log.error("Exception", ioException);
  }
}

2. constructor İçinde Exception Fırlatılırsa
Sadece finally işletilir
Örnek
Elimizde şöyle bir kod olsun
public static class Resource implements AutoCloseable {

  public Resource() throws Exception {
    throw new Exception("Exception from constructor");
  }

  public void doSomething() throws Exception {
    throw new Exception("Exception from method");
  }

  @Override
  public void close() throws Exception {
    throw new Exception("Exception from closeable");
  }
}

public static void main(String[] args) {
  try(Resource r = new Resource()) {
    r.doSomething();
  } catch (Exception ex) {
    ex.printStackTrace();
  }
}
Yakalanan exception nesnesinin detailMessage alanında "Exception from constructor" görürüz. 

3. try İçinde Exception Fırlatılırsa
Throwable nesnesinin suppressed alanında görebiliriz.

Örnek
Şöyle yaparız
try (Connection c = DriverManager.getConnection(url)) {
    work();
} catch (Exception e) {
    throw new Error("Insert failed", e);
}
Eğer hem work() hem de Connection.close() metodu içinde exception fırlatılırsa close() tarafından fırlatılan exception Throwable nesnesinin suppressed alanında görürüz.
Açıklaması şöyle
This will close your connection or generally the passed AutoCloseable appropriately. And will handle the shadowing of the exception by using the Throwable.addSuppressed() method.
Çıktı olarak şuna benzer bir şey alırız. Koyu kısım suppressed olan ve close() metodundan gelen exception.
>>> work()
  >>> close()
  MyException: Exception in work()
    at AutoClose.work(AutoClose.java:11)
    at AutoClose.main(AutoClose.java:16)    Suppressed: java.lang.RuntimeException: Exception in close()
      at AutoClose.close(AutoClose.java:6)
      at AutoClose.main(AutoClose.java:17)