Этот начал меня в истинный OOA& D.
Применение UML и Шаблонов: Введение в Объектно-ориентированный Анализ и проектирование и Итерационную разработку - Craig Larman
Они произошли бы там также:
Оценка основных ответов со сравнительным тестом производительности, который подтверждает опасения, что текущий выбранный ответ делает дорогостоящие regex операции под капотом
До настоящего времени, предоставленные ответы появляются в 3 основных стиля (игнорирующий ответ JavaScript ;)):
С точки зрения размера кода ясно, String.replace является самым кратким. Простая реализация Java является немного меньшей и более чистой (по моему скромному мнению), чем Лямбда (не понимайте меня превратно - я часто использую Лямбды, где они являются соответствующими)
, скорость Выполнения была, в порядке самого быстрого к самому медленному: простая реализация Java, Лямбда и затем String.replace () (который вызывает regex).
Безусловно самая быстрая реализация была простой реализацией Java, настроенной так, чтобы она предварительно выделила буфер StringBuilder макс. возможной длине результата и затем просто добавила символы к буферу, которые не находятся в "символах для удаления" строки. Это избегает, чтобы любой перераспределил, который произошел бы для Строк> 16 символов в длине (выделение по умолчанию для StringBuilder), и это избегает "слайда, оставленного" хит производительности удаления символов из копии строки, которая происходит, реализация Лямбды.
код ниже выполняет простое эталонное тестирование, выполняя каждую реализацию 1,000,000 раз и регистрирует прошедшее время.
точные результаты меняются в зависимости от каждого выполнения, но порядок производительности никогда не изменяется:
Start simple Java implementation
Time: 157 ms
Start Lambda implementation
Time: 253 ms
Start String.replace implementation
Time: 634 ms
реализация Лямбды (как скопировано с ответа Kaplan) может быть медленнее, потому что это выполняет "сдвиг, оставленный один" всех символов направо от удаляемого символа. Это, очевидно, ухудшилось бы для более длинных строк с большим количеством символов, требующих удаления. Также могли бы быть немного служебные в самой реализации Лямбды.
реализация String.replace, использует regex и делает regex "компиляция" в каждом вызове. Оптимизация этого должна была бы использовать regex непосредственно и кэшировать скомпилированный шаблон для предотвращения стоимости компиляции его каждый раз.
package com.sample;
import java.util.function.BiFunction;
import java.util.stream.IntStream;
public class Main {
static public String deleteCharsSimple(String fromString, String charsToDelete)
{
StringBuilder buf = new StringBuilder(fromString.length()); // Preallocate to max possible result length
for(int i = 0; i < fromString.length(); i++)
if (charsToDelete.indexOf(fromString.charAt(i)) < 0)
buf.append(fromString.charAt(i)); // char not in chars to delete so add it
return buf.toString();
}
static public String deleteCharsLambda(String fromString1, String charsToDelete)
{
BiFunction<String, String, String> deleteChars = (fromString, chars) -> {
StringBuilder buf = new StringBuilder(fromString);
IntStream.range(0, buf.length()).forEach(i -> {
while (i < buf.length() && chars.indexOf(buf.charAt(i)) >= 0)
buf.deleteCharAt(i);
});
return (buf.toString());
};
return deleteChars.apply(fromString1, charsToDelete);
}
static public String deleteCharsReplace(String fromString, String charsToDelete)
{
return fromString.replace(charsToDelete, "");
}
public static void main(String[] args)
{
String str = "XXXTextX XXto modifyX";
String charsToDelete = "X"; // Should only be one char as per OP's requirement
long start, end;
System.out.println("Start simple");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++)
deleteCharsSimple(str, charsToDelete);
end = System.currentTimeMillis();
System.out.println("Time: " + (end - start));
System.out.println("Start lambda");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++)
deleteCharsLambda(str, charsToDelete);
end = System.currentTimeMillis();
System.out.println("Time: " + (end - start));
System.out.println("Start replace");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++)
deleteCharsReplace(str, charsToDelete);
end = System.currentTimeMillis();
System.out.println("Time: " + (end - start));
}
}