User Andrey
Andrey
26 уровень

Java String. Вопросы к собеседованию и ответы на них, ч.1

Статья из группы Архив info.javarush.ru
Класс String один из наиболее широко используемых классов в Java. В статье приведены некоторые важные вопросы к собеседованию по Java String и ответы на них. Java String. Вопросы к собеседованию и ответы на них, ч.1 - 1Они будут очень полезны для получения полного представления о классе String и подготовят к любому вопросу, касающемуся класса String на собеседовании.

1. Что такое String в Java? Какой это тип данных?

String — это класс в Java, который прописан в пакете java.lang. Это не примитивный тип данных, как int и long. Класс String представляет строковый набор символов. Строки используются практически по всех Java-приложениях, и есть несколько фактов, которые мы должны знать о классе String. Это неизменяемый (immutable) и финализированный тип данных в Java и все объекты класса String виртуальная машина хранит в пуле строк. Еще одной особенностью String является способ получения объектов класса String используя двойные кавычки и перегружая оператор “+” для конкатенации.

2. Какие есть способы создания объекта String?

Мы можем создавать объекты используя оператор new, как и для любого другого класса в Java или мы можем использовать двойные кавычки для создания объекта String. Также есть несколько конструкторов класса String для получения строки из массива символов, массива байтов, а также используя StringBuffer или StringBuilder.

String str = new String("abc");
String str1 = "abc";
Когда мы создаем строку используя двойные кавычки, виртуальная машина Java ищет в пуле строк другую строку с таким же значением. Если строка найдена, то возвращается только ссылка на существующий объект класса String, иначе создается новый объект с полученным значением, и сохраняется в пул. Когда мы используем оператор new, виртуальная машина создает объект String, но не хранит его в пуле строк. Мы можем использовать метод intern() для сохранения строки в пуле строк, или получения ссылки, если такая строка уже находится в пуле.

3. Напишите метод проверки, является ли строка палиндромом.

Строка называется палиндромом, если она одинаково читается в обоих направлениях. К примеру “аба” является строкой-палиндромом. Класс String не предоставляет никакого метода для реверса строки, зато классы StringBuffer и StringBuilder имеют метод реверсирования, при помощи которого мы можем проверить, является ли наша строка палиндромом или нет.

private static boolean isPalindrome(String str) {
        if (str == null)
            return false;
        StringBuilder strBuilder = new StringBuilder(str);
        strBuilder.reverse();
        return strBuilder.toString().equals(str);
    }
Иногда собеседующий может попросить не использовать другие классы для этой проверки, в таком случае мы можем сравнивать символы в строке с обоих сторон для проверки на палиндром.

private static boolean isPalindromeString(String str) {
        if (str == null)
            return false;
        int length = str.length();
        System.out.println(length / 2);
        for (int i = 0; i < length / 2; i++) {

            if (str.charAt(i) != str.charAt(length - i - 1))
                return false;
        }
        return true;
    }

4. Напишите метод удаления данного символа из строки.

Мы можем использовать метод replaceAll для замены всех вхождений в строку другой строкой. Обратите внимание на то, что метод получает в качестве аргумента строку, поэтому мы используем класс Character для создания строки из символа, и используем её для замены всех символов на пустую строку.

private static String removeChar(String str, char ch) {
        if (str == null)
            return null;
        return str.replaceAll(Character.toString(ch), "");
    }

5. Как мы можем перевести строку в верхний регистр или нижний регистр?

Мы можем использовать методы класса String toUpperCase и toLowerCace для получения строки в верхнем и в нижнем регистре. Эти методы имеют перегруженный вариант, принимающий аргумент Locale, и используют его правила локализации для преобразования строки в верхний или нижний регистр.

6. Что делает метод subSequence?

Java 1.4 ввела интерфейс CharSequence, класс String наследует этот интерфейс, и это единственная причина реализации метода subSequence в классе String. Внутри он вызывает метод substring. Простой пример использования метода:

public class StringSubsequence {

    public static void main(String[] args) {
        String str = "www.journaldev.com";
        System.out.println("Last 4 char String: "+str.subSequence(str.length()-4, str.length()));
        System.out.println("First 4 char String: "+str.subSequence(0, 4));
        System.out.println("website name: "+str.subSequence(4, 14));
        
        //substring vs subSequence
        System.out.println("substring == subSequence ? "
			+(str.substring(4, 14) == str.subSequence(4, 14)));
       
        System.out.println("substring equals subSequence ? "
			+(str.substring(4, 14).equals(str.subSequence(4, 14))));
    }
}
На выходе программа покажет следующее:

Last 4 char String: .com
First 4 char String: www.
website name: journaldev
substring == subSequence ? false
substring equals subSequence ? true
В идеале вы должны всегда использовать метод substring.

7. Как сравнить две строки в Java?

Класс String наследует интерфейс Comparable и имеет два варианта метода compareTo(). Метод compareTo(String anotherString) сравнивает объект String с полученным аргументом String лексикографически. Если текущая строка предшествует полученной строке, метод возвращает отрицательное значение типа integer, и если строка следует за полученным аргументом, то возвращает положительное значение integer. Если метод возвращает 0, значит строка имеет то же значение, в таком случае метод equals(String str) так же вернет true. compareToIgnoreCase(String str): этот метод подобен предыдущему, за исключением того, что он игнорирует регистр символов. Он использует CASE_INSENSITIVE_ORDER Comparator для регистронезависимого сравнения. Если возвращаемое значение равно нулю, тогда метод equalsIgnoreCase(String str) так же вернет true. Давайте рассмотрим небольшой пример, объясняющий эти методы:

public class StringCompareToExample {
    public static void main(String[] args) {
        String str = "ABC";
        System.out.println(str.compareTo("DEF"));
        System.out.println(str.compareToIgnoreCase("abc"));
    }
}
Программа выведет следующее:

-3
0

8. Как преобразовать строку в символ и обратно?

Это вопрос с подвохом, поскольку строка – это последовательность символов, поэтому мы можем преобразовать её только в единичный символ. Мы можем использовать метод charAt для получения символа, находящегося в указанной позиции или мы можем использовать метод toCharArray() для преобразования строки в массив символов. Простой пример, показывающий как преобразовать строку в символ и символ в строку в Java.

import java.util.Arrays;
 
public class StringToCharToString {
    public static void main(String[] args) {
        //String to char array
        String str = "123";
        char[] chArr = str.toCharArray();
        System.out.println("String to char array: "+Arrays.toString(chArr));
        //String to char
        char c = str.charAt(1);
        System.out.println("String to char: "+c);
        //char to String
        String s = Character.toString(c);
        System.out.println("char to String: "+s);
        //удалить все заданные символы из строки
        System.out.println("removing all chars from String: "
                                 +removeCharFromString("1ABCD12DW", '1'));
    }
 
    private static String removeCharFromString(String str, char c) {
        return str.replaceAll(Character.toString( c ), "");
    }
}
Программа выведет следующее:

String to char array: [1, 2, 3]
String to char: 2
char to String: 2
removing all chars from String: ABCD2DW

9. Как преобразовать строку в массив байтов и обратно?

Мы можем использовать метод getBytes() для преобразования строки в массив байтов и мы можем использовать конструктор new String(byte[] arr) для преобразования массива байтов в строку.

import java.util.Arrays;
 
public class StringByteArray {
     public static void main(String[] args) {
        String str = "www.journaldev.com";
        //преобразование String в byte array
        byte[] byteArr = str.getBytes();
        System.out.println("String to byte array : "+Arrays.toString(byteArr));
        //преобразование byte array и String
        String str1 = new String(byteArr);
        System.out.println("byte array to String : "+str1);
        //посмотрим, str и str1 одинаковые или нет
        System.out.println("str == str1? " + (str == str1));
        System.out.println("str.equals(str1)? " + (str.equals(str1)));
    }
}
Программа выведет следующее:

String to byte array : [119, 119, 119, 46, 106, 111, 117, 114, 110, 97, 108, 100, 101, 118, 46, 99, 111, 109]
byte array to String : www.journaldev.com
str == str1? false
str.equals(str1)? true

10. Можем ли мы использовать строку в конструкции switch.

Этот хитрый вопрос, используется для проверки ваших знаний о текущем развитии языка. Java 7 расширяет возможности оператора switch для использования строк, ранние версии Java не поддерживают этого. Если вы реализуете условный поток для строк, вы можете использовать условия if-else и вы можете использовать оператор switch, если используете Java 7 или поздние версии. Небольшой пример использования строки в операторе switch и другой метод, который показывает такую же логику, используя условия if-else.

public class SwitchStringExample {

    public static void main(String[] args) {
        printColorUsingSwitch("red");
        printColorUsingIf("red");
        // оператор switch регистрозависимый
        printColorUsingSwitch("RED");
        printColorUsingSwitch(null);
    }
 
    private static void printColorUsingIf(String color) {
        if (color.equals("blue")) {
            System.out.println("BLUE");
        } else if (color.equals("red")) {
            System.out.println("RED");
        } else {
            System.out.println("INVALID COLOR CODE");
        }
    }
 
    private static void printColorUsingSwitch(String color) {
        switch (color) {
        case "blue":
            System.out.println("BLUE");
            break;
        case "red":
            System.out.println("RED");
            break;
        default:
            System.out.println("INVALID COLOR CODE");
        }
    }
}
Программа выведет следующее:

RED
RED
INVALID COLOR CODE
Exception in thread "main"
java.lang.NullPointerException
    at com.journaldev.util.SwitchStringExample.printColorUsingSwitch(SwitchStringExample.java:24)
    at com.journaldev.util.SwitchStringExample.main(SwitchStringExample.java:10)
Ключевые моменты использования switch для строк в Java.
  • использование строк в конструкции switch делает код читабельнее, убирая множественные цепи условий if-else.
  • строки в switch чувствительны к регистру, пример выше показывает это.
  • оператор switch использует метод String.equals() для сравнения полученного значения со значениями case, поэтому добавьте проверку на NULL во избежание NullPointerException.
  • согласно документации Java 7 для строк в switch, компилятор Java формирует более эффективный байткод для строк в конструкции switch, чем для сцепленных условий if-else.
  • убедитесь, что это будет использоваться с Java 7 или поздней версии, иначе получите xception.

11. Напишите программу, печатающую все перестановки строки.

Это непростой вопрос, и мы должны использовать рекурсию для нахождения всех перестановок строки, например перестановками “AAB” могут быть “AAB”, “ABA” и “BAA”. Также нам необходимо использовать Set для того, чтобы убедиться, что у нас нет дубликатов строк. Для получения всех перестановок, мы для начала берем первый символ строки и переставляем оставшиеся символы. Если String = “ABC” Первый символ char = A и оставшиеся перестановки BC и CB. Теперь мы можем вставить первый символ в доступные позиции в перестановках. BC -> ABC, BAC, BCA CB -> ACB, CAB, CBA Пример программы:

import java.util.HashSet;
import java.util.Set;
 
public class StringHelper {
    public static Set<String> permutationFinder(String str) {
        Set<String> perm = new HashSet<String>();
        //Handling error scenarios
        if (str == null) {
            return null;
        } else if (str.length() == 0) {
            perm.add("");
            return perm;
        }
        char initial = str.charAt(0); // первый символ
        String rem = str.substring(1); // полная строка без первого символа
        Set<String> words = permutationFinder(rem);
        for (String strNew : words) {
            for (int i = 0;i<=strNew.length();i++){
                perm.add(charInsert(strNew, initial, i));
            }
        }
        return perm;
    }
 
    public static String charInsert(String str, char c, int j) {
        String begin = str.substring(0, j);
        String end = str.substring(j);
        return begin + c + end;
    }
 
    public static void main(String[] args) {
        String s = "AAC";
        String s1 = "ABC";
        String s2 = "ABCD";
        System.out.println("\nPermutations for " + s + " are: \n" + permutationFinder(s));
        System.out.println("\nPermutations for " + s1 + " are: \n" + permutationFinder(s1));
        System.out.println("\nPermutations for " + s2 + " are: \n" + permutationFinder(s2));
    }
}
Вывод программы:

Permutations for AAC are: 
[AAC, ACA, CAA]
 
Permutations for ABC are: 
[ACB, ABC, BCA, CBA, CAB, BAC]
 
Permutations for ABCD are: 
[DABC, CADB, BCAD, DBAC, BACD, ABCD, ABDC, DCBA, ADBC, ADCB, CBDA, CBAD, DACB, ACBD, CDBA, CDAB, DCAB, ACDB, DBCA, BDAC, CABD, BADC, BCDA, BDCA]
Продолжение статьи
Комментарии (16)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
S1ndr0m Уровень 10, Тула, Russian Federation
11 августа 2022
"Когда мы используем оператор new, виртуальная машина создает объект String, но не хранит его в пуле строк." А где она его хранит?
SWK Уровень 24
11 июня 2022

Это неизменяемый (immutable) и финализированный тип данных в Java и 
все объекты класса String виртуальная машина хранит в пуле строк.
через несколько предложений:

Когда мы используем оператор new, виртуальная машина создает объект String, 
но не хранит его в пуле строк.
ТщательнЕЕ надо переводить...
Elena Vasilyeva Уровень 34, Казань, Россия
22 мая 2022
Ответ на вопрос №6 не понятен, очень сложно и неполноценно описано. Гуглим, первая же страничка показывает наглядный пример и лаконично объясняет назначение метода.
Анастасия Киселева Уровень 22, Минск, Belarus
24 марта 2022
И часто ли так подробно могут спрашивать про string?
🦔 Виктор Уровень 20, Москва, Россия Expert
5 декабря 2020
Еле дочитал до конца, на пол пути срубило. Есть вопросы, есть ответы, но нет доступного объяснения. Спасибо за труды, но получился просто справочник примеров по стрингам. -- tlgrm: @LetsCodeIt | @SefoNotasi
Slavaslav Уровень 34, Киев
28 октября 2016
11. Напишите программу, печатающую все перестановки строки.
public class PermutationString {
    public static void main(String[] args) {
        String s = "abab";
        for (String s1 : permutations(s)) {
            System.out.println(s1);
        }
    }

    private static Set<String> permutations(String inputString) {
        Set<String> strings = new HashSet<>();
        permutations("", inputString, strings);
        return strings;
    }

    private static void permutations(String pref, String inputStr, Set<String> strings) {
        if (inputStr.length() > 1) {
            for (int i = 0; i < inputStr.length(); i++) {
                permutations(pref + inputStr.charAt(i), inputStr.substring(0, i) + inputStr.substring(i + 1), strings);
            }
        } else if (inputStr.length() == 1) {
            strings.add(pref + inputStr);
        }
    }
}
SergioShapoval Уровень 41, Киев, Россия
1 июля 2015
Хороший пример про перестановки
KeLsTaR Уровень 24, Минск, Беларусь
10 февраля 2014
8. Как преобразовать строку в символ и обратно?
Условие звучит так, будто исходная строка и состоит из одного символа. Если она состоит из нескольких то конечно charAt(i), но если строка состоит из одного символа и ее надо просто преобразовать в символ, довольно просто это сделать через Character.valueOf(str)

9. Как преобразовать строку в массив символов и обратно?

Тут я вообще не понял при чем тут массив байт в ответе, ведь в условии массив символов, и ответом выше вы пользовались прекрасным методом ,toCharArray() который собственно и делает то что надо (преобразовывает строку в массив символов), а для обратного преобразования есть метод String.valueOf(char[] carr) так что это всего на две строчки решение
Treefeed Уровень 21
8 февраля 2014