我有List
String
个,我想trim()
列表中的每个元素。
目前,我正在使用ArrayList
,对元素进行简单循环,并将修剪后的元素添加到返回列表中,如下所示:
int listLen = listToTrim.size();
List<String> trimmedList = new ArrayList<String>( listLen );
for ( int i = 0; i < listLen; i++ ) {
trimmedList.add( listToTrim.get( i ).trim() );
}
return trimmedList;
对于大型列表,是否有更有效的方法可以做到这一点?
答案 0 :(得分:14)
不,你很好。它的效率和它一样高效。没有魔法可以避免迭代。
要记住一点,但是:如果listToTrim
不是随机访问列表(即它不实现RandomAccess
),然后使用Iterator
(或内部使用Iterator
的增强型for循环)而不是传统的for循环通常更有效。不显示List
的最值得注意的RandomAccess
是LinkedList
。在l.get(300)
上使用600个元素调用LinkedList
将需要遍历~300个元素才能获得正确的元素!
修改代码以使用增强的for循环看起来像这样:
public List<String> trimStrings(Listy<String> listToTrim) {
List<String> trimmedList = new ArrayList<String>(listToTrim.size());
for (String str : listToTrim) {
trimmedList.add(str.trim());
}
return trimmedList;
}
如果您不再需要原始列表,那么重新使用原始列表可以节省内存并提高性能:
public void trimStringsInPlace(List<String> listToTrim) {
ListIterator<String> it = listToTrim.listIterator();
while (it.hasNext()) {
it.set(it.next().trim());
}
}
答案 1 :(得分:3)
不是真的;你必须在每个元素上调用trim
,并且尽可能快地预先分配正确大小的ArrayList
。 Java 8将允许您使语法更紧凑,但迭代和trim
ming是这里的最小工作量。
答案 2 :(得分:3)
此外,您可以使用ArrayList#set()而不是创建新的ArrayList。这可以大大减少大型列表的内存占用。
for ( int i = 0; i < listLen; i++ ) {
listToTrim.set(i,listToTrim.get( i ).trim());
}
答案 3 :(得分:3)
约阿希姆已经回答了这个问题。但有一个建议 -
listToTrim - 当您向listToTrim添加项目时,请在添加之前先修剪。这样,您就不必迭代,修改或创建另一个列表。这听起来不合逻辑。
根据评论编辑:
String fruits = "Apple, Banana , Mango, Passion Fruit, Grapes ";
List<String> fruitList = Arrays.asList((fruits.trim()).split("\\s*,\\s*")); // Trim first and then regex matches spaces before and after comma
for(String fruit : fruitList){
System.out.println("Fruit: " + fruit + "\tLength: " + fruit.length());
}
<强>输出:强>
Fruit: Apple Length: 5
Fruit: Banana Length: 6
Fruit: Mango Length: 5
Fruit: Passion Fruit Length: 13
Fruit: Grapes Length: 6
答案 4 :(得分:3)
约阿希姆做对了。人们说你应该修剪你的字符串,然后把它们放在第一个列表中也是正确的。
无论如何,如果后者不适合您,可能会有另一种方法:您确定要使用所有修剪过的琴弦吗?或者你会只使用其中的一些,比如说,可能只有前五个?然后修剪它们可能是一种过度杀伤。
您可以设计一个特殊的List
实现来存储原始列表,但会给出修剪过的元素。这就是我的意思:
public class ImmutableStringTrimmingList extends AbstractList<String> {
private final List<String> stringList;
public ImmutableStringTrimmingList(List<String> stringList) {
this.stringList = stringList;
}
@Override
public String get(int index) {
return stringList.get(index).trim();
}
@Override
public int size() {
return stringList.size();
}
}
ImmutableStringTrimmingList
存储原始列表(因此对该列表的任何更改也将在此处传播),并将String
个对象拉出来进行延迟修剪。如果您不想做任何不必要的工作,这可能会有所帮助,因为它只会修剪get()
请求的字符串。它还可以适用于缓存修剪过的对象,这样就不必每次都重新修改它。但如果您觉得这门课有帮助,那对您来说就是一种做法。
或者,如果你是一个Guava用户,你可以使用Lists.transform()
基本上做同样的事情,也懒得。
List<String> trimmedList = Lists.transform(list, new Function<String, String>() {
@Override
public String apply(String input) {
return input.trim();
}
});