Проблемы при использовании StringBuilder вместо String

Имеется HashSet<String> list = new HashSet<String>() и два метода для работы с ним:

    void addL(String[][] field) {

    String current = new String();
    
    for(int r=0; r<4 ; r++){
        for(int c=0; c<10 ; c++){
            current += String.valueOf(field[r][c]);             
        }
    }
    list.add(current);      
}

boolean repeatL(String[][] field, String side) {
    
    String current = new String();
    
    for(int r=0; r<4 ; r++){
        for(int c=0; c<10 ; c++){
            current += String.valueOf(field[r][c]);             
        }
    }
            
    if(side=="white" & list.contains(current)){
        return true;
    }
    else{
        return false;
    }
}

В таком виде всё работает без проблем, хотя и не быстро.

Затем в справочниках прочитал, что при "активном" использовании циклов для производительности лучше StringBuilder вместо String. Заменил везде одно на другое (и конкатенацию, соответственно, на append) - поначалу работает нормально, но через некоторое время вылетает с ошибкой превышения размера StringBuilder. Установил определённый параметр capacity: здесь вылеты прекратились, зато они появились в другом месте программы (при работе с большим количеством ArrayList -ов) с ошибкой OutOfMemoryError: Java heap space. Непонятно, что не так, если использование String наоборот, должно потреблять больше ресурсов...

Менял на такое:

    HashSet<StringBuilder> list = new HashSet<StringBuilder>();

void addL(String[][] field) {

    int r = field.length;
    int c = field[0].length;
    
    StringBuilder current = new StringBuilder(field.length * field[0].length);
    
    for(r=0; r<field.length ; r++){
        for(c=0; c<field[0].length ; c++){
            current.append(field[r][c]);                
        }
    }
    list.add(current);      
}

boolean repeatL(String[][] field, String side) {
    
    int r = field.length;
    int c = field[0].length;
    
    StringBuilder current = new StringBuilder(field.length * field[0].length);
    
    for(r=0; r<field.length ; r++){
        for(c=0; c<field[0].length ; c++){
            current.append(field[r][c]);                
        }
    }
            
    if(side=="white" & list.contains(current)){
        return true;
    }
    else{
        return false;
    }
}

Ответы (2 шт):

Автор решения: V-CHO

Такой вариант тоже вроде рабочий, но даёт ли он выигрыш в производительности по сравнению с изначальным я не знаю...

    HashSet<String> list = new HashSet<String>();

void addL(String[][] field) {

    int r = field.length;
    int c = field[0].length;
    
    StringBuilder current = new StringBuilder(field.length * field[0].length);
    
    for(r=0; r<field.length ; r++){
        for(c=0; c<field[0].length ; c++){
            current.append(field[r][c]);                
        }
    }
    String hash = current.toString();
    list.add(hash);     
}

boolean repeatL(String[][] field, String side) {
    
    int r = field.length;
    int c = field[0].length;
    
    StringBuilder current = new StringBuilder(field.length * field[0].length);
    
    for(r=0; r<field.length ; r++){
        for(c=0; c<field[0].length ; c++){
            current.append(field[r][c]);                
        }
    }
    
    String hash = current.toString();
            
    if(side=="white" & list.contains(hash)){
        return true;
    }
    else{
        return false;
    }
→ Ссылка
Автор решения: Vaiker

Попробуйте так:

HashSet<String> list = new HashSet<>();
void addL(String[][] field) {
    StringBuilder current = new StringBuilder();
    for (int i = 0; i < field.length; i++) {
        for (int j = 0; j < field[0].length; j++)
            current.append(field[i][j]);
    }
    list.add(current.toString());
}

boolean repeatL(String[][] field, String side) {
    StringBuilder current = new StringBuilder();
    for (int i = 0; i < field.length; i++) {
        for (int j = 0; j < field[0].length; j++)
            current.append(field[i][j]);
    }
    return (side.equals("white") && list.contains(current.toString()));
}
→ Ссылка