Java 增强的for with remove运行效率更高

Java 增强的for with remove运行效率更高,java,performance,for-loop,Java,Performance,For Loop,以下代码本身位于定义了oldChar的外部循环中: List<Character> modifiableCollection = new ArrayList<Character>(Arrays.asList(AlphabeticalStatistics.ALL_LETTERS)); for (int j = 0; j < modifiableCollection.size(); j++) { Character letterOfAlphabet = modi

以下代码本身位于定义了
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;
    }
}
,但当我使用常规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;
}

这个程序的目的是破译替换密文

I使用索引for循环(
for int I=0;I Character.valueOf((char)c)).collect(Collectors.toList());
ArrayList copy=新的ArrayList(字母列表);
列表不可修改AlphabetList=集合。不可修改列表(副本);
double timeA=检查时间(迭代次数,()->{
List modifiableCollection=新的ArrayList(alphabetList);
modifiableCollection.removeIf(下一步->选中删除(下一步));
});
System.out.println(“A:+timeA”);
double timeB=检查时间(迭代次数,()->{
List modifiableCollection=新的ArrayList(alphabetList);
迭代器迭代器=modifiableCollection.Iterator();
while(iterator.hasNext()){
if(checkRemove(iterator.next())){
iterator.remove();
打破
}
}
});
System.out.println(“B:+timeB”);
double timeC=检查时间(迭代次数,()->{
List modifiableCollection=新的ArrayList(alphabetList);
int size=modifiableCollection.size();
对于(int i=0;i{
List modifiableCollection=新的ArrayList(alphabetList);
for(字符c:不可修改的字母列表){
如果(选中删除(c)){
可修改的集合。删除(c);
打破
}
}
});
System.out.println(“D:+定时);
}
私有静态布尔checkRemove(下一个字符){
返回next.equals('W');
}
专用静态双重检查时间(长计数,可运行fn){
列表差异=新的ArrayList();
for(int i=0;il)
.average()
.orElse(0升);
收益率平均值;
}
A:247.68729885
B:83.9981085
C:63.98897325
D:91.69348503

是什么让您认为for循环是这里的瓶颈?我担心的是,在将字符传递给
replaceLetters()
方法之前,需要将字符转换为字符串。如果此方法对字符串进行替换,则很可能会创建一个新的
String
对象,如果您希望优化字符串处理操作,则通常不需要该对象。向我们展示您的
replaceLetters
;很有可能这会占用大部分时间。让我们知道整个代码的目的是什么,因为它可以用不同的方法更有效地完成。checkTime是在哪里定义的?我所做的是在程序的开始和结束时使用
System.currentTimeMillis()
,然后进行减法。我添加了使用的校验时间,我想我也像你一样完成了。对我来说,B大于D~你提取了
size()
操作的变量吗?~不过,这些都是纳秒。这对您的实际用例有影响吗?我已经基本解决了我的问题,但我还有一个问题:为什么即使我从列表中删除了一些东西,增强的for循环仍然有效?
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;
}
 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