Добавить уникальные буквы данной строки в список
Я хочу добавить строковые буквы в список, но я хочу только добавить каждую букву один раз. Например, если строка "HELLO AM CHRISTOS WHITE", некоторые буквы появляются более одного раза, поэтому я хочу, чтобы они добавлялись только один раз.
Я думаю о двух циклах:
for (int i=0; i< str.length(); i++){
for(int j=0; j< str.length(); j++){
if (str.charAt(i) != str.charAt(j)) {
myList.add(charAt(i));
}
}
}
Но этот код не избегает дубликатов.
Ответы
Ответ 1
Было бы более эффективно использовать LinkedHashSet
для определения уникальных символов. Если вы используете LinkedHashSet
, порядок уникальных символов входной строки будет сохранен.
После одного цикла, который займет линейное время, вы можете добавить все уникальные символы к вашему выводу List
.
Set<Character> unique = new LinkedHashSet<>();
for (int i = 0; i < str.length(); i++){
unique.add(str.charAt(i));
}
myList.addAll(unique);
Ответ 2
Чтобы предотвратить дублирование в коллекции, вам не нужно List
, вам нужен Set
(например, HashSet
).
Если вы хотите сохранить заказ, добавляете свои String
s, используйте LinkedHashSet
.
Наконец, если вы хотите, чтобы ваш Set
естественно отсортировал ваш String
(или чтобы отсортировать их с помощью Comparator
), используйте TreeSet
.
Пример
String foo = "ghghababcdef";
Set<String> hash = new HashSet<>();
Set<String> linked = new LinkedHashSet<>();
Set<String> tree = new TreeSet<>();
// iterating characters
for (char c: foo.toCharArray()) {
// adding String representation of character to each set
hash.add(Character.toString(c));
linked.add(Character.toString(c));
tree.add(Character.toString(c));
}
// printing...
System.out.println(hash);
System.out.println(linked);
System.out.println(tree);
Выход
[a, b, c, d, e, f, g, h] // this may vary
[g, h, a, b, c, d, e, f] // keeps insertion order
[a, b, c, d, e, f, g, h] // sorted lexicographically by default
Ответ 3
в качестве альтернативы ответе Set
, если вы хотите придерживаться решения List
.
Вам нужно всего лишь выполнить цикл и использовать метод List.contains(Object)
и проверить, присутствует ли текущий char
в вашем List
.
String str = "HELLO AM CHRISTOS WHITE";
List<Character> myList = new ArrayList<>();
for(int i=0; i< str.length(); i++){
if (!myList.contains(str.charAt(i))) {
myList.add(str.charAt(i));
}
}
for(char c : myList) {
System.out.println(c);
}
Выход
HELO AMCRISTW
Ответ 4
j
не назначается. Я предполагаю, что он инициализирован 0, поэтому исключение не существует
Если вы измените второй цикл на for(int j=0; j< str.length(); j++)
, он все равно не будет работать, он не будет печатать буквы, которые дублируются в строке.
Итак, подумайте о том, какой диапазон j нужно перебирать. Вы хотите напечатать любую букву, которая еще не произошла в строке, если вы получите мой jist.
Ответ 5
К сожалению, в Java 8 нет потока символов, но здесь есть способ Java 8:
str.chars().distinct().mapToObj(c -> (char) c).collect(Collectors.toList());
Он может быть менее эффективным, но это читаемый один лайнер, и он показывает мощь потоков.