44

将 List 或 Set 的每个元素小写的最有效方法是什么?

我对列表的想法:

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 来说会是什么样子?由于目前没有对 Set(或 List)的每个元素应用操作的方法,是否可以在不创建额外的临时 Set 的情况下完成?

像这样的东西会很好:

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

谢谢,

4

11 回答 11

117

另一个解决方案,但使用 Java 8 及更高版本:

List<String> result = strings.stream()
                             .map(String::toLowerCase)
                             .collect(Collectors.toList());
于 2015-06-28T20:05:36.060 回答
32

这似乎是一个相当干净的列表解决方案。它应该允许使用特定的 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));
}
于 2010-04-15T11:16:36.030 回答
13

你可以用谷歌收藏做到这一点:

    Collection<String> lowerCaseStrings = Collections2.transform(strings,
        new Function<String, String>() {
            public String apply(String str) {
                return str.toLowerCase();
            }
        }
    );
于 2010-04-15T11:22:41.133 回答
5

如果您可以在此处更改输入列表,这是实现它的另一种方法。

strings.replaceAll(String::toLowerCase)

于 2019-01-09T08:07:08.247 回答
4

好吧,由于两个事实,没有真正优雅的解决方案:

  • StringJava 中的 s 是不可变的
  • Java 没有像函数式语言那样为您提供真正好的map(f, list)功能。

渐近地说,您无法获得比当前方法更好的运行时间。您必须使用创建一个新字符串,toLowerCase()并且您需要自己遍历列表并生成每个新的小写字符串,并将其替换为现有字符串。

于 2010-04-15T11:10:03.007 回答
2

尝试使用 Commons Collections中的 CollectionUtils#transform 来获得就地解决方案,或者如果您需要实时视图,请尝试使用 Guava 中的 Collections2#transform 。

于 2010-04-15T11:14:18.373 回答
1

这可能更快:

for(int i=0,l=strings.size();i<l;++i)
{
  strings.set(i, strings.get(i).toLowerCase());
}
于 2010-04-15T11:04:23.080 回答
0

如果您将字符串更改为 Set,我认为不可能就地进行操作(无需创建另一个集合)。这是因为您只能使用迭代器或 for each 循环对 Set 进行迭代,并且在这样做时不能插入新对象(它会引发异常)

于 2010-04-15T11:14:55.210 回答
0

参考公认的(Matthew T. Staebler's)解决方案中的 ListIterator 方法。使用 ListIterator 如何比这里的方法更好?

public static Set<String> replace(List<String> strings) {
    Set<String> set = new HashSet<>();
    for (String s: strings)
        set.add(s.toLowerCase());
    return set;
}
于 2012-05-07T22:25:35.313 回答
0

使用 JAVA 8 并行流它变得更快

List<String> output= new ArrayList<>();
List<String> input= new ArrayList<>();
input.add("A");
input.add("B");
input.add("C");
input.add("D");
input.stream().parallel().map((item) -> item.toLowerCase())
            .collect(Collectors.toCollection(() -> output));
于 2016-08-05T10:31:57.520 回答
0

我一直在寻找类似的东西,但是因为我的ArrayList对象没有被声明为GENERIC并且它可以从某个地方作为原始List类型对象使用而被卡住了。我刚刚得到一个ArrayList对象“_products”。所以,下面提到了我所做的,它对我非常有用::

List<String> dbProducts = _products;
    for(int i = 0; i<dbProducts.size(); i++) {
        dbProducts.add(dbProducts.get(i).toLowerCase());         
    }

也就是说,我首先获取了可用的_products并创建了一个GENERIC列表对象(因为我只获得了相同的字符串)然后我对列表元素应用了toLowerCase()方法,该方法以前由于非泛型ArrayList对象而无法工作。

而我们这里使用的toLowerCase()方法是String类的。

字符串 java.lang.String.toLowerCase()

不是ArrayListObject类。

如果我错了,请纠正。JAVA新手求指导。:)

于 2015-12-18T12:08:57.987 回答