以下代码本身位于定义了oldChar
的外部循环中:
List<Character> modifiableCollection = new ArrayList<Character>(Arrays.asList(AlphabeticalStatistics.ALL_LETTERS));
for (int j = 0; j < modifiableCollection.size(); j++) {
Character letterOfAlphabet = modifiableCollection.get(j);
String loaAsString = letterOfAlphabet.toString();
if (replaceLetters(Character.toString(oldChar), loaAsString)) {
modifiableCollection.remove(j);
System.out.println(oldChar + " was replaced with " + loaAsString);
break;
}
}
我正在尝试遍历ALL_LETTERS
尽可能有效地进行迭代。对于每个元素,我要检查该字母和另一个字母上的replaceLetters()
。如果是这样,该字母将被替换,而我想将其从modifiableCollection
中删除,因此下一次循环时,它不会再替换该字母。
但是,我看到的是使用增强的for循环WITH REMOVAL,代码运行AND是更有效。我在must not remove中增强了功能:
for (Character letterOfAlphabet : modifiableCollection) {...remove()} // Compiles
,但是当我像上面那样使用常规的for循环时,该程序需要更长的运行时间;当我使用迭代器时,该程序需要花费更长的时间才能运行。我应该坚持使用foreach循环吗?
编辑replaceLetters()
方法:
protected boolean replaceLetters(String toReplace, String replacement, String toAdd, String toAdd2) {
if (replacedLetters.contains(toAdd2) || solvedLetters.contains(toAdd))
return false;
return isCorrect(toReplace, replacement, toAdd, toAdd2);
}
private boolean isCorrect(String toReplace, String replacement, String toAdd, String toAdd2) {
String newText = getText().replace(toReplace, replacement);
if (Arrays.stream(newText.split(" "))
.filter(w -> {
return w.contains(replacement) && AlphabeticalStatistics.needsNoLetters(w);
})
.noneMatch(w -> {
return !EnglishDeterminer.isWord(w);
})
) {
setText(newText);
solvedLetters.add(toAdd);
replacedLetters.add(toAdd2);
return true;
}
return false;
}
此程序的目的是解密替换密文。
我似乎使用索引循环(for int i=0; i<size; i++
)更快。由于您不必比较集合值以找到匹配项,因此删除索引的速度可能也会更快。也许您应该为modifiableCollection.size()
提取一个变量,因为它将在每次迭代时进行评估。
public static final int ITERATIONS = 100000000;
public static void main(String[] args) {
List<Character> alphabetList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmopqrstuvwxyz123456789".chars()
.mapToObj(c -> Character.valueOf((char) c)).collect(Collectors.toList());
ArrayList<Character> copy = new ArrayList<>(alphabetList);
List<Character> unmodifiableAlphabetList = Collections.unmodifiableList(copy);
double timeA = checkTime(ITERATIONS, () -> {
List<Character> modifiableCollection = new ArrayList<>(alphabetList);
modifiableCollection.removeIf(next -> checkRemove(next));
});
System.out.println("A : " + timeA);
double timeB = checkTime(ITERATIONS, () -> {
List<Character> modifiableCollection = new ArrayList<>(alphabetList);
Iterator<Character> iterator = modifiableCollection.iterator();
while (iterator.hasNext()) {
if (checkRemove(iterator.next())) {
iterator.remove();
break;
}
}
});
System.out.println("B : " + timeB);
double timeC = checkTime(ITERATIONS, () -> {
List<Character> modifiableCollection = new ArrayList<>(alphabetList);
int size = modifiableCollection.size();
for (int i = 0; i < size; i++) {
Character character = unmodifiableAlphabetList.get(i);
if (checkRemove(character)) {
modifiableCollection.remove(i);
break;
}
}
});
System.out.println("C : " + timeC);
double timeD = checkTime(ITERATIONS, () -> {
List<Character> modifiableCollection = new ArrayList<>(alphabetList);
for (Character c : unmodifiableAlphabetList) {
if (checkRemove(c)) {
modifiableCollection.remove(c);
break;
}
}
});
System.out.println("D : " + timeD);
}
private static boolean checkRemove(Character next) {
return next.equals('W');
}
private static double checkTime(long count, Runnable fn) {
List<Long> diffs = new ArrayList<>();
for (int i = 0; i < count; i++) {
long now = System.nanoTime();
fn.run();
long after = System.nanoTime();
long nanoDiff = after - now;
diffs.add(nanoDiff);
}
double average = diffs.stream()
.mapToLong(l -> l)
.average()
.orElse(0L);
return average;
}
A : 247.68729885
B : 83.9981085
C : 63.98897325
D : 91.69348503