Java 루프의 For 및 For-each 애플리케이션 비교 분석

王林
풀어 주다: 2023-05-25 14:56:08
앞으로
1134명이 탐색했습니다.

for-each 구현 방법

For-each는 새로운 구문이 아니라 Java용 구문 설탕입니다. 컴파일 타임에 컴파일러는 이 코드를 반복기 구현으로 변환하고 바이트코드로 컴파일합니다.javap-verbose-Testforeach명령을 실행하여 다음 컴파일된 코드를 디컴파일할 수 있습니다.javap-verbose-Testforeach反编译以下编译代码:

public class TestForeach { List integers; public void testForeach(){ for(Integer i : integers){ } } }
로그인 후 복사

获得的详细字节码如下:

public void testForeach(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=3, args_size=1 0: aload_0 1: getfield #2 // Field integers:Ljava/util/List; 4: invokeinterface #3, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator; 9: astore_1 10: aload_1 11: invokeinterface #4, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z 16: ifeq 32 19: aload_1 20: invokeinterface #5, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object; 25: checkcast #6 // class java/lang/Integer 28: astore_2 29: goto 10 32: return LineNumberTable: line 11: 0 line 13: 29 line 14: 32 LocalVariableTable: Start Length Slot Name Signature 29 0 2 i Ljava/lang/Integer; 0 33 0 this Ltest/TestForeach; }
로그인 후 복사

此字节码的一般含义是使用getfileld命令来获取integers变量并且调用List.iterator来获取迭代器实例和调用iterator.hasNext。如果返回true,调用iterator.next

public class ForLoopTest { public static void main(String[] args) { List arrayList = new ArrayList<>(); for (int i = 0; i < 10000000; i++) { arrayList.add(i); } long arrayListStartTime = System.currentTimeMillis(); for (int i = 0; i < arrayList.size(); i++) { arrayList.get(i); } long arrayListCost =System.currentTimeMillis()-arrayListStartTime; System.out.println("ArrayList for loop traversal cost: "+ arrayListCost); long arrayListForeachStartTime = System.currentTimeMillis(); for (Integer integer : arrayList) { } long arrayListForeachCost =System.currentTimeMillis()-arrayListForeachStartTime; System.out.println("ArrayList foreach traversal cost: "+ arrayListForeachCost);
로그인 후 복사
얻은 자세한 바이트코드는 다음과 같습니다.

rrreee

이 바이트코드의 일반적인 의미는 를 사용한다는 것입니다. getfileld명령을 사용하여 integers변수를 가져오고 List.iterator를 호출하여 반복기 인스턴스를 가져오고 iterator.hasNext를 호출합니다. true가 반환되면 iterator.next메서드를 호출하세요.

이것은 컬렉션을 순회하는 반복자의 구현 논리입니다.

Benchmarking

이제 for 루프 방식과 for-each 방식을 사용해 테스트해 보겠습니다.

rrreeeJava 루프의 For 및 For-each 애플리케이션 비교 분석테스트 결과는 다음과 같습니다.

보시다시피 결과는 명백합니다. For 루프 메서드를 사용하는 것은 For Each 메서드보다 ArrayList에서 더 효율적입니다.


for 루프가 for-each보다 낫다고 말할 수 있나요?

답은 '아니오'입니다. 다음 벤치마크에서는 ArrayList를 LinkedList로 변경합니다.Java 루프의 For 및 For-each 애플리케이션 비교 분석다시한번 테스트 결과입니다.

원인 분석


일부 초보자는 ArrayList가 for 루프 방법을 사용하여 더 빠르게 탐색하는 반면 LinkedList는 느리고 매우 느린 이유를 궁금해할 수 있습니다.

이는 ArrayList 및 LinkedList 데이터 구조에 의해 결정됩니다.

ArrayList는 배열을 사용하여 아래에 요소를 저장합니다. 배열은 연속적인 메모리 공간입니다. 인덱스를 통해 데이터를 얻을 수 있습니다. 시간 복잡도는 O(1)이므로 빠릅니다.

LinkedList의 맨 아래 레이어는 이중 연결 리스트입니다. for 루프를 사용하여 매번 연결된 목록의 헤드 노드부터 시작하여 순회를 구현합니다. 시간 복잡도는 O(n*n)입니다.
  • 결론

  • for-each는 반복자로 구현되고 동시 수정 확인을 수행해야 하기 때문에 ArrayList를 사용할 때 for 루프 방법이 더 빠릅니다.

  • LinkedList를 사용할 때 LinkedList는 이중 연결 목록을 사용하여 구현되므로 for-each가 for 루프보다 훨씬 빠릅니다. 모든 주소 지정은 헤드 노드에서 시작되어야 합니다. LinkedList를 순회할 때 for 루프를 사용하지 마십시오.

반복자 패턴을 사용하면 for-each는 컬렉션의 특정 구현에 신경 쓸 필요가 없습니다. 컬렉션을 교체해야 하는 경우 코드를 수정하지 않고도 쉽게 수행할 수 있습니다.

위 내용은 Java 루프의 For 및 For-each 애플리케이션 비교 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:yisu.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!