Ana cevapların, mevcut seçili cevabın kaputun altında pahalı regex operasyonları yaptığına dair endişeleri doğrulayan bir performans ölçütü ile değerlendirilmesi
Bugüne kadar verilen cevaplar 3 ana stilde gelmektedir (JavaScript cevabını yok saymak;)):
- String.replace (charsToDelete, "") kullanın; başlık altında normal ifade kullanan
- Lambda kullanın
- Basit Java uygulamasını kullanın
Kod boyutu açısından açıkça String.replace en kısa olanıdır. Basit Java uygulaması Lambda'dan biraz daha küçük ve daha temiz (IMHO) (beni yanlış anlamayın - Lambdas'ı uygun olan yerlerde sık sık kullanıyorum)
Yürütme hızı, en hızlıdan en yavaşına doğru: basit Java uygulaması, Lambda ve sonra String.replace () (regex'i çağırır) idi.
Şimdiye kadar en hızlı uygulama, StringBuilder arabelleğini olası maksimum sonuç uzunluğuna önceden yerleştirecek ve daha sonra "silinecek karakter" dizesinde olmayan arabelleğe chars ekleyecek şekilde ayarlanmış basit Java uygulamasıydı. Bu, Dizeler> 16 karakter uzunluğunda (StringBuilder için varsayılan ayırma) oluşacak yeniden tahsisleri engeller ve oluşan dizenin bir kopyasından karakterleri silmenin "slayt sola" performans ismini Lambda uygulamasıdır.
Aşağıdaki kod, her bir uygulamayı 1.000.000 kez çalıştıran basit bir karşılaştırma testi gerçekleştirir ve geçen süreyi kaydeder.
Kesin sonuçlar her çalışmaya göre değişir, ancak performans sırası asla değişmez:
Start simple Java implementation
Time: 157 ms
Start Lambda implementation
Time: 253 ms
Start String.replace implementation
Time: 634 ms
Lambda uygulaması (Kaplan'ın cevabından kopyalandığı gibi) daha yavaş olabilir, çünkü silinmekte olan karakterin sağındaki tüm karakterlerden "bir sola kaydırma" gerçekleştirir. Bu, silme gerektiren birçok karakter içeren daha uzun dizeler için daha da kötüleşir. Ayrıca Lambda uygulamasının kendisinde bir miktar ek yük olabilir.
String.replace uygulaması, regex kullanır ve her çağrıda bir regex "compile" yapar. Bunun bir optimizasyonu, regex'i doğrudan kullanmak ve her seferinde derleme maliyetini önlemek için derlenen deseni önbelleğe almak olacaktır.
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));
}
}