Как к нижнему регистру каждый элемент набора эффективно?

Что самым эффективным путем является к нижнему регистру каждый элемент Списка или Набора?

Моя идея для Списка:

final List<String> strings = new ArrayList<String>();
strings.add("HELLO");
strings.add("WORLD");

for(int i=0,l=strings.size();i<l;++i)
{
  strings.add(strings.remove(0).toLowerCase());
}

Существует ли лучший, более быстрый путь? Как этот пример был бы похож для Набора? Как в настоящее время нет никакого метода для применения операции к каждому элементу Набора (или Список), это может быть сделано, не создавая дополнительный временный Набор?

Что-то вроде этого было бы хорошо:

Set<String> strings = new HashSet<String>();
strings.apply(
  function (element)
  { this.replace(element, element.toLowerCase();) } 
);

Спасибо,

39
задан egallardo 15 April 2013 в 23:49
поделиться

6 ответов

Это кажется довольно чистым решением для списков. Он должен позволять использовать конкретную реализацию List для обеспечения реализации, оптимальной как для обхода списка - за линейное время - так и для замены строки - за постоянное время.

public static void replace(List<String> strings)
{
    ListIterator<String> iterator = strings.listIterator();
    while (iterator.hasNext())
    {
        iterator.set(iterator.next().toLowerCase());
    }
}

Это лучшее, что я могу придумать для наборов. Как уже говорили другие, операция не может быть выполнена на месте в наборе по ряду причин. Строку нижнего регистра, возможно, потребуется поместить в другое место в наборе, чем строка, которую она заменяет. Более того, строчная строка может вообще не быть добавлена ​​к набору, если она идентична другой строчной строке, которая уже была добавлена ​​(например, «HELLO» и «Hello» оба дадут «hello», что приведет к добавляется в набор только один раз).

public static void replace(Set<String> strings)
{
    String[] stringsArray = strings.toArray(new String[0]);
    for (int i=0; i<stringsArray.length; ++i)
    {
        stringsArray[i] = stringsArray[i].toLowerCase();
    }
    strings.clear();
    strings.addAll(Arrays.asList(stringsArray));
}
28
ответ дан 27 November 2019 в 02:04
поделиться

Попробуйте преобразовать CollectionUtils # в Commons Collections для решения на месте или Collections2 # преобразовать в Guava если вам нужен живой просмотр.

2
ответ дан 27 November 2019 в 02:04
поделиться

Я не верю, что можно выполнять манипуляции на месте (без создания другой Коллекции), если вы измените строки на Набор. Это связано с тем, что вы можете перебирать Set только с помощью итератора или для каждого цикла и не можете вставлять новые объекты при этом (это вызывает исключение)

0
ответ дан 27 November 2019 в 02:04
поделиться

Это можно сделать с помощью Коллекций Google:

    Collection<String> lowerCaseStrings = Collections2.transform(strings,
        new Function<String, String>() {
            public String apply(String str) {
                return str.toLowerCase();
            }
        }
    );
13
ответ дан 27 November 2019 в 02:04
поделиться

Это, вероятно, быстрее:

for(int i=0,l=strings.size();i<l;++i)
{
  strings.set(i, strings.get(i).toLowerCase());
}
1
ответ дан 27 November 2019 в 02:04
поделиться

Что ж, настоящего элегантного решения не существует из-за двух фактов:

  • Строки в Java неизменяемы
  • Java не дает вам действительно хорошая функция map (f, list) , как и в функциональных языках.

Говоря асимптотически, вы не можете получить лучшее время выполнения, чем ваш текущий метод. Вам нужно будет создать новую строку, используя toLowerCase () , и вам нужно будет самостоятельно перебирать список и генерировать каждую новую строку в нижнем регистре, заменяя ее существующей.

4
ответ дан 27 November 2019 в 02:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: