Jak działa pętla Java 'for each'?
Rozważmy:
List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList
for (String item : someList) {
System.out.println(item);
}
Jak wyglądałaby równoważna pętla for
bez użycia dla każdej składni?
27 answers
for (Iterator<String> i = someIterable.iterator(); i.hasNext();) {
String item = i.next();
System.out.println(item);
}
Zauważ, że jeśli chcesz użyć i.remove();
w swojej pętli lub uzyskać dostęp do rzeczywistego iteratora w jakiś sposób, nie możesz użyć idiomu for ( : )
, ponieważ rzeczywisty iterator jest tylko wnioskowany.
Jak zauważył Denis Bueno, kod ten działa dla każdego obiektu, który implementuje Iterable
Interfejs .
Ponadto, jeśli prawa strona idiomu for (:)
jest obiektem array
, a nie obiektem Iterable
, kod wewnętrzny używa licznika indeksu int i zamiast tego sprawdza array.length
. Zobacz też Specyfikacja Języka Java .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-03 16:16:09
Konstrukcja dla każdego jest również ważna dla tablic. np.
String[] fruits = new String[] { "Orange", "Apple", "Pear", "Strawberry" };
for (String fruit : fruits) {
// fruit is an element of the `fruits` array.
}
Który jest zasadniczo odpowiednikiem
for (int i = 0; i < fruits.length; i++) {
String fruit = fruits[i];
// fruit is an element of the `fruits` array.
}
Tak więc, ogólne podsumowanie:
[nsayer] Oto dłuższa forma tego, co się dzieje:
for(Iterator<String> i = someList.iterator(); i.hasNext(); ) { String item = i.next(); System.out.println(item); }
Zwróć uwagę, że jeśli potrzebujesz użyć I. remove (); in your loop, or access rzeczywisty iterator w jakiś sposób, ty nie można użyć idiomu for (:), ponieważ rzeczywisty Iterator jest jedynie wywnioskować.
To wynika z odpowiedzi nsayer, ale warto zauważyć, że OP jest dla(..) składnia będzie działać, gdy "someList" jest wszystko, co implementuje java.lang.Iterable -- nie ma być listą, albo jakąś kolekcją z java.util. Nawet własne typy, dlatego może być stosowany z tym składnia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:06:59
The foreach
loop , dodany w Java 5 (zwany także "enhanced For loop"), jest odpowiednikiem java.util.Iterator
--to cukier składniowy do tego samego. Dlatego podczas czytania każdego elementu, Jeden po drugim i w kolejności, foreach
powinien być zawsze wybierany zamiast iteratora, ponieważ jest wygodniejszy i bardziej zwięzły.
Foreach
for(int i : intList) {
System.out.println("An element in the list: " + i);
}
Iterator
Iterator<Integer> intItr = intList.iterator();
while(intItr.hasNext()) {
System.out.println("An element in the list: " + intItr.next());
}
Są sytuacje, w których musisz użyć Iterator
bezpośrednio. Na przykład, próba Usuń element używając foreach
can (will?) wynik w ConcurrentModificationException
.
foreach
vs. for
: podstawowe różnice
Jedyną praktyczną różnicą między for
a foreach
jest to, że w przypadku obiektów indeksowalnych nie masz dostępu do indeksu. Przykład, gdy podstawowa pętla for
jest wymagana:
for(int i = 0; i < array.length; i++) {
if(i < 5) {
// Do something special
} else {
// Do other stuff
}
}
Chociaż można ręcznie utworzyć osobny indeks int-zmienna z foreach
,
int idx = -1;
for(int i : intArray) {
idx++;
...
}
Nie jest to zalecane, ponieważ zakres zmienny nie jest idealny, a Podstawowa pętla for
jest po prostu standardowym i oczekiwanym formatem dla tego przypadku użycia.
foreach
vs. for
: wydajność
Podczas uzyskiwania dostępu do kolekcji, foreach
jest znacznie szybszy niż podstawowy dostęp pętli for
. Jednak podczas uzyskiwania dostępu do tablic-przynajmniej w przypadku tablic prymitywnych i wrapper-arrays-dostęp przez indeksy jest znacznie szybszy.
Różnica między iteratorem a indeksem dostępu dla prymitywnych int-arrays
Indeksy są 23-40 procent szybciej niż Iteratory przy dostępie do tablic int
lub Integer
. Poniżej znajduje się wyjście z klasy testing na dole tego posta, która sumuje liczby w 100-elementowej tablicy primitive-int (a to iterator, B to indeks): {]}
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 358,597,622 nanoseconds
Test B: 269,167,681 nanoseconds
B faster by 89,429,941 nanoseconds (24.438799231635727% faster)
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 377,461,823 nanoseconds
Test B: 278,694,271 nanoseconds
B faster by 98,767,552 nanoseconds (25.666236154695838% faster)
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 288,953,495 nanoseconds
Test B: 207,050,523 nanoseconds
B faster by 81,902,972 nanoseconds (27.844689860906513% faster)
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 375,373,765 nanoseconds
Test B: 283,813,875 nanoseconds
B faster by 91,559,890 nanoseconds (23.891659337194227% faster)
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 375,790,818 nanoseconds
Test B: 220,770,915 nanoseconds
B faster by 155,019,903 nanoseconds (40.75164734599769% faster)
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 326,373,762 nanoseconds
Test B: 202,555,566 nanoseconds
B faster by 123,818,196 nanoseconds (37.437545972215744% faster)
Uruchomiłem również to dla Integer
tablicy, i indeksy są nadal wyraźnym zwycięzcą, ale tylko między 18 a 25 procent szybciej.
Dla zbiorów Iteratory są szybsze niż indeksy
Dla List
z Integers
, jednak Iteratory są wyraźnym zwycięzcą. Po prostu zmień tablicę int w klasie testowej na:
List<Integer> intList = Arrays.asList(new Integer[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100});
I dokonać niezbędnych zmian w funkcji testowej (int[]
do List<Integer>
, length
do size()
, itd.):
[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 3,429,929,976 nanoseconds
Test B: 5,262,782,488 nanoseconds
A faster by 1,832,852,512 nanoseconds (34.326681820485675% faster)
[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,907,391,427 nanoseconds
Test B: 3,957,718,459 nanoseconds
A faster by 1,050,327,032 nanoseconds (26.038700083921256% faster)
[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,566,004,688 nanoseconds
Test B: 4,221,746,521 nanoseconds
A faster by 1,655,741,833 nanoseconds (38.71935684115413% faster)
[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,770,945,276 nanoseconds
Test B: 3,829,077,158 nanoseconds
A faster by 1,058,131,882 nanoseconds (27.134122749113843% faster)
[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 3,467,474,055 nanoseconds
Test B: 5,183,149,104 nanoseconds
A faster by 1,715,675,049 nanoseconds (32.60101667104192% faster)
[C:\java_code\]java TimeIteratorVsIndexIntList 1000000
Test A: 3,439,983,933 nanoseconds
Test B: 3,509,530,312 nanoseconds
A faster by 69,546,379 nanoseconds (1.4816434912159906% faster)
[C:\java_code\]java TimeIteratorVsIndexIntList 1000000
Test A: 3,451,101,466 nanoseconds
Test B: 5,057,979,210 nanoseconds
A faster by 1,606,877,744 nanoseconds (31.269164666060377% faster)
W jednym teście są prawie równoważne, ale ze zbiorami iterator wygrywa.
*ten post jest oparty na dwóch odpowiedziach, które napisałem na Stack Overflow:
Trochę więcej informacji: która jest bardziej wydajna, pętla for-each, czy iterator?
Pełna klasa testowa
Stworzyłem tę klasę porównywania-czasu-potrzebny-do-zrobienia-dowolnych-dwóch-rzeczy po przeczytaniu tego pytania na Stack Overflow:
import java.text.NumberFormat;
import java.util.Locale;
/**
<P>{@code java TimeIteratorVsIndexIntArray 1000000}</P>
@see <CODE><A HREF="https://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-java">https://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-java</A></CODE>
**/
public class TimeIteratorVsIndexIntArray {
public static final NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
public static final void main(String[] tryCount_inParamIdx0) {
int testCount;
// Get try-count from a command-line parameter
try {
testCount = Integer.parseInt(tryCount_inParamIdx0[0]);
}
catch(ArrayIndexOutOfBoundsException | NumberFormatException x) {
throw new IllegalArgumentException("Missing or invalid command line parameter: The number of testCount for each test. " + x);
}
//Test proper...START
int[] intArray = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100};
long lStart = System.nanoTime();
for(int i = 0; i < testCount; i++) {
testIterator(intArray);
}
long lADuration = outputGetNanoDuration("A", lStart);
lStart = System.nanoTime();
for(int i = 0; i < testCount; i++) {
testFor(intArray);
}
long lBDuration = outputGetNanoDuration("B", lStart);
outputGetABTestNanoDifference(lADuration, lBDuration, "A", "B");
}
private static final void testIterator(int[] int_array) {
int total = 0;
for(int i = 0; i < int_array.length; i++) {
total += int_array[i];
}
}
private static final void testFor(int[] int_array) {
int total = 0;
for(int i : int_array) {
total += i;
}
}
//Test proper...END
//Timer testing utilities...START
public static final long outputGetNanoDuration(String s_testName, long l_nanoStart) {
long lDuration = System.nanoTime() - l_nanoStart;
System.out.println("Test " + s_testName + ": " + nf.format(lDuration) + " nanoseconds");
return lDuration;
}
public static final long outputGetABTestNanoDifference(long l_aDuration, long l_bDuration, String s_aTestName, String s_bTestName) {
long lDiff = -1;
double dPct = -1.0;
String sFaster = null;
if(l_aDuration > l_bDuration) {
lDiff = l_aDuration - l_bDuration;
dPct = 100.00 - (l_bDuration * 100.0 / l_aDuration + 0.5);
sFaster = "B";
}
else {
lDiff = l_bDuration - l_aDuration;
dPct = 100.00 - (l_aDuration * 100.0 / l_bDuration + 0.5);
sFaster = "A";
}
System.out.println(sFaster + " faster by " + nf.format(lDiff) + " nanoseconds (" + dPct + "% faster)");
return lDiff;
}
//Timer testing utilities...END
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:35:45
Oto odpowiedź, która nie zakłada znajomości iteratorów Javy. Jest mniej precyzyjny, ale przydatny w edukacji.
Podczas programowania często piszemy kod, który wygląda następująco:
char[] grades = ....
for(int i = 0; i < grades.length; i++) { // for i goes from 0 to grades.length
System.out.print(grades[i]); // Print grades[i]
}
Składnia foreach pozwala na zapisanie tego wspólnego wzorca w bardziej naturalny i mniej hałaśliwy sposób.
for(char grade : grades) { // foreach grade in grades
System.out.print(grade); // print that grade
}
Dodatkowo ta składnia jest ważna dla obiektów takich jak listy lub zestawy, które nie obsługują indeksowania tablic, ale które implementują Javę Iterowalny interfejs.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:12:45
Pętla for-each w Javie wykorzystuje podstawowy mechanizm iteratora. Jest więc identyczny z następującym:
Iterator<String> iterator = someList.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:04:16
Zgodnie z definicją w JLS for-każda pętla może mieć dwie formy:
-
Jeśli typ wyrażenia jest podtypem
Iterable
, to translacja jest następująca:List<String> someList = new ArrayList<String>(); someList.add("Apple"); someList.add("Ball"); for (String item : someList) { System.out.println(item); } // IS TRANSLATED TO: for(Iterator<String> stringIterator = someList.iterator(); stringIterator.hasNext(); ) { String item = stringIterator.next(); System.out.println(item); }
-
Jeśli wyrażenie koniecznie ma typ tablicy
T[]
to:String[] someArray = new String[2]; someArray[0] = "Apple"; someArray[1] = "Ball"; for(String item2 : someArray) { System.out.println(item2); } // IS TRANSLATED TO: for (int i = 0; i < someArray.length; i++) { String item2 = someArray[i]; System.out.println(item2); }
Java 8 wprowadziła strumienie, które działają ogólnie lepiej. Możemy ich używać jako:
someList.stream().forEach(System.out::println);
Arrays.stream(someArray).forEach(System.out::println);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-20 09:12:52
Wynika to z odpowiedzi nsayer, ale warto zauważyć, że OP jest dla (..) składnia będzie działać, gdy "someList" to cokolwiek implementującego Javę.lang.Iterable - nie musi to być lista, ani jakaś kolekcja z Javy.util. Z tą składnią można więc korzystać nawet z własnych typów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:05:36
W Javie 8 funkcji można użyć tego:
List<String> messages = Arrays.asList("First", "Second", "Third");
void forTest(){
messages.forEach(System.out::println);
}
Wyjście
First
Second
Third
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-25 15:43:15
Składnia pętli foreach to:
for (type obj:array) {...}
Przykład:
String[] s = {"Java", "Coffe", "Is", "Cool"};
for (String str:s /*s is the array*/) {
System.out.println(str);
}
Wyjście:
Java
Coffe
Is
Cool
Ostrzeżenie: możesz uzyskać dostęp do elementów tablicy za pomocą pętli foreach, ale nie możesz ich zainicjować. Użyj do tego oryginalnej pętli for
.
Ostrzeżenie: musisz dopasować typ tablicy do innego obiektu.
for (double b:s) // Invalid-double is not String
Jeśli chcesz edytować elementy, użyj oryginalnej pętli for
w następujący sposób:
for (int i = 0; i < s.length-1 /*-1 because of the 0 index */; i++) {
if (i==1) //1 because once again I say the 0 index
s[i]="2 is cool";
else
s[i] = "hello";
}
Teraz, jeśli wrzucimy s do konsoli, otrzymamy:
hello
2 is cool
hello
hello
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:16:36
Konstrukcja pętli Java "for-each" pozwoli na iterację dwóch typów obiektów:
-
T[]
(tablice dowolnego typu) java.lang.Iterable<T>
Interfejs Iterable<T>
posiada tylko jedną metodę: Iterator<T> iterator()
. Działa to na obiektach typu Collection<T>
, ponieważ interfejs Collection<T>
rozszerza Iterable<T>
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 18:04:18
Pojęcie pętli foreach, jak wspomniano w Wikipedii, jest podkreślone poniżej:
W przeciwieństwie do innych konstrukcji pętli for, pętle forach Zwykle utrzymanie bez wyraźnego licznika: zasadniczo mówią "zrób to, aby wszystko w tym zestawie", a nie "zrób to x razy". Pozwala to uniknąć potencjalne błędy off-by-one i sprawia, że kod jest łatwiejszy do odczytania.
Tak więc pojęcie pętli foreach opisuje, że pętla nie używa żadnego jawnego licznika co oznacza, że nie ma potrzeby używania indeksów do poruszania się po liście, dzięki czemu oszczędza to Użytkownika od błędu off-by-one. Aby opisać ogólne pojęcie tego błędu off-by-one, weźmy przykład pętli do przemierzania listy za pomocą indeksów.
// In this loop it is assumed that the list starts with index 0
for(int i=0; i<list.length; i++){
}
Ale załóżmy, że jeśli lista zaczyna się od indeksu 1, to ta pętla wyrzuci wyjątek, ponieważ nie znajdzie elementu w indeksie 0 i ten błąd jest nazywany błędem off-by-one. Aby więc uniknąć tego błędu, koncepcja foreach pętla jest używana. Mogą być też inne zalety, ale to jest to, co moim zdaniem jest główną koncepcją i zaletą korzystania z pętli foreach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:14:37
W Javie 8 wprowadzili forEach. Za pomocą listy można zapętlać Mapy.
Loop a List using for each
List<String> someList = new ArrayList<String>();
someList.add("A");
someList.add("B");
someList.add("C");
someList.forEach(listItem -> System.out.println(listItem))
Lub
someList.forEach(listItem-> {
System.out.println(listItem);
});
Loop a Map using for each
Map<String, String> mapList = new HashMap<>();
mapList.put("Key1", "Value1");
mapList.put("Key2", "Value2");
mapList.put("Key3", "Value3");
mapList.forEach((key,value)->System.out.println("Key: " + key + " Value : " + value));
Lub
mapList.forEach((key,value)->{
System.out.println("Key : " + key + " Value : " + value);
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-30 13:23:15
for (Iterator<String> itr = someList.iterator(); itr.hasNext(); ) {
String item = itr.next();
System.out.println(item);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-19 09:58:20
Używając starszych wersji Javy, w tym Java 7
Można używać pętli foreach
w następujący sposób.
List<String> items = new ArrayList<>();
items.add("A");
items.add("B");
items.add("C");
items.add("D");
items.add("E");
for(String item : items){
System.out.println(item);
}
Poniżej znajduje się najnowszy sposób użycia pętli foreach
w Java 8
(loop a List with forEach
+ lambda expression or method reference)
//lambda
//Output : A,B,C,D,E
items.forEach(item->System.out.println(item));
//method reference
//Output : A,B,C,D,E
items.forEach(System.out::println);
Więcej informacji można znaleźć pod tym linkiem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-21 11:05:15
Oto równoważne wyrażenie.
for(Iterator<String> sit = someList.iterator(); sit.hasNext(); ) {
System.out.println(sit.next());
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 16:48:10
Zauważ również, że użycie metody "foreach" w pytaniu pierwotnym ma pewne ograniczenia, takie jak niemożność usunięcia elementów z listy podczas iteracji.
Nowa pętla for jest łatwiejsza do odczytania i eliminuje potrzebę oddzielnego iteratora, ale jest naprawdę użyteczna tylko w przejściach iteracji tylko do odczytu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 16:53:52
Alternatywa dla forEach w celu uniknięcia "dla każdego":
List<String> someList = new ArrayList<String>();
Wariant 1 (zwykły):
someList.stream().forEach(listItem -> {
System.out.println(listItem);
});
Variant 2 (parallel execution (faster)):
someList.parallelStream().forEach(listItem -> {
System.out.println(listItem);
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:38:25
Dodaje piękno twojemu kodowi, usuwając wszystkie podstawowe zapętlenia. Daje to czysty wygląd kodu, uzasadniony poniżej.
Normal for
loop:
void cancelAll(Collection<TimerTask> list) {
for (Iterator<TimerTask> i = list.iterator(); i.hasNext();)
i.next().cancel();
}
Użycie for-each:
void cancelAll(Collection<TimerTask> list) {
for (TimerTask t : list)
t.cancel();
}
Dla-każdy jest konstruktem nad zbiorem, który implementuje Iterator . Pamiętaj, że Twoja kolekcja powinna zaimplementować Iterator ; w przeciwnym razie nie możesz go używać Z for-each.
Następujący wiersz jest odczytywany jako "dla każdej TimerTask t na liście."
for (TimerTask t : list)
Jest mniejsza szansa na błędy w przypadku for-each. Nie musisz się martwić o zainicjalizowanie iteratora lub zainicjowanie licznika pętli i jego zakończenie (tam gdzie jest miejsce na błędy).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-31 20:02:43
Przed uruchomieniem Java 8, należy użyć:
Iterator<String> iterator = someList.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
}
Jednak wraz z wprowadzeniem strumieni w Javie 8 można zrobić to samo w znacznie mniejszej składni. Na przykład dla twojego someList
możesz zrobić:
someList.stream().forEach(System.out::println);
Więcej o streamach znajdziesz tutaj .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:40:15
Wyglądałoby to mniej więcej tak. Bardzo chytry.
for (Iterator<String> i = someList.iterator(); i.hasNext(); )
System.out.println(i.next());
Jest dobry writeup na dla każdego w dokumentacji Sun .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:05:04
Jak wiele dobrych odpowiedzi powiedziało, obiekt musi zaimplementować Iterable interface
, jeśli chce użyć pętli for-each
.
Zamieszczę prosty przykład i postaram się wyjaśnić w inny sposób, jak działa pętla for-each
.
Przykład pętli for-each
:
public class ForEachTest {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("111");
list.add("222");
for (String str : list) {
System.out.println(str);
}
}
}
Następnie, jeśli użyjemy javap
do dekompilacji tej klasy, otrzymamy próbkę kodu bajtowego:
public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=4, args_size=1
0: new #16 // class java/util/ArrayList
3: dup
4: invokespecial #18 // Method java/util/ArrayList."<init>":()V
7: astore_1
8: aload_1
9: ldc #19 // String 111
11: invokeinterface #21, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
16: pop
17: aload_1
18: ldc #27 // String 222
20: invokeinterface #21, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
25: pop
26: aload_1
27: invokeinterface #29, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
Jak widać z ostatniego wiersza próbki, kompilator automatycznie przekonwertuje użycie słowa kluczowego for-each
na użycie Iterator
w czasie kompilacji. Może to wyjaśniać, dlaczego obiekt, który nie implementuje Iterable interface
, rzuci Exception
, gdy spróbuje użyć pętli for-each
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-31 20:05:03
The Java for each loop (aka enhanced for loop) jest uproszczoną wersją pętli for. Zaletą jest to, że jest mniej kodu do napisania i mniej zmiennych do zarządzania. Minusem jest to, że nie masz kontroli nad wartością kroku i nie masz dostępu do indeksu pętli wewnątrz ciała pętli.
Są one najlepiej używane, gdy wartość step jest prostym przyrostem o 1 i gdy potrzebujesz tylko dostępu do elementu Pętli Prądowej. Na przykład, jeśli musisz zapętlić każdy element w tablica lub Kolekcja bez zaglądania do przodu lub za bieżącym elementem.
Nie ma inicjalizacji pętli, nie ma warunku logicznego, a wartość kroku jest niejawna i jest prostym przyrostem. Dlatego są one uważane za o wiele prostsze niż zwykłe dla pętli.
Enhanced for loops follow this order of execution:
1) Korpus pętli
2) powtórz od kroku 1 do przejścia całej tablicy lub kolekcji
Przykład-Integer Array
int [] intArray = {1, 3, 5, 7, 9};
for(int currentValue : intArray) {
System.out.println(currentValue);
}
Zmienna currentValue przechowuje bieżącą wartość zapętloną w tablicy intArray. Zauważ, że nie ma jawnej wartości kroku-zawsze jest to przyrost o 1.
Dwukropek może oznaczać "w". Tak więc deklaracja enhanced for loop stwierdza: loop over intArray i zapisuje bieżącą tablicę int wartość w zmiennej currentValue.
Wyjście:
1
3
5
7
9
Przykład-String Array
Możemy użyć for - każda pętla do iteracji nad tablicą łańcuchów. Deklaracja pętli mówi: loop over myStrings String array i przechowuje bieżącą wartość W zmiennej currentString.
String [] myStrings = {
"alpha",
"beta",
"gamma",
"delta"
};
for(String currentString : myStrings) {
System.out.println(currentString);
}
Wyjście:
alpha
beta
gamma
delta
Example-List
Pętla enhanced for może być również używana do iteracji w Javie.util.Lista wygląda następująco:List<String> myList = new ArrayList<String>();
myList.add("alpha");
myList.add("beta");
myList.add("gamma");
myList.add("delta");
for(String currentItem : myList) {
System.out.println(currentItem);
}
Deklaracja loop stwierdza: loop over myList List of Strings and store the current List value in the zmienna currentItem.
Wyjście:
alpha
beta
gamma
delta
Przykład-Zestaw
Pętla enhanced for może być również używana do iteracji w Javie.util.Ustaw w następujący sposób:Set<String> mySet = new HashSet<String>();
mySet.add("alpha");
mySet.add("alpha");
mySet.add("beta");
mySet.add("gamma");
mySet.add("gamma");
mySet.add("delta");
for(String currentItem : mySet) {
System.out.println(currentItem);
}
Deklaracja loop stwierdza: loop over Myset Set of Strings and store the current set value in The currenttitem variable. Zauważ, że ponieważ jest to zbiór, zduplikowane wartości łańcuchowe nie są przechowywane.
Wyjście:
alpha
delta
beta
gamma
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-02 13:11:27
public static Boolean Add_Tag(int totalsize)
{ List<String> fullst = new ArrayList<String>();
for(int k=0;k<totalsize;k++)
{
fullst.addAll();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-27 11:55:00
Idiom Java for-each może być stosowany tylko do tablic lub obiektów typu *Iterable. Ten idiom to implicit Jak to naprawdę wspierane przez iteratora. Iterator jest programowany przez programistę i często używa indeksu integer lub węzła (w zależności od struktury danych) do śledzenia jego pozycji. Na papierze jest wolniejszy niż zwykła pętla for, a najmniej dla" liniowych " struktur, takich jak tablice i listy, ale zapewnia większą abstrakcję.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-18 17:43:28
Jak wiele innych odpowiedzi poprawnie stwierdza, for
each
loop
jest tylko składniowy cukier nad tym samym starym for
loop
a kompilator tłumaczy to na tą samą starą pętlę for.
javac (open jdk) posiada przełącznik -XD-printflat
, który generuje plik java z usuniętym cukrem składniowym. pełna Komenda wygląda tak:
javac -XD-printflat -d src/ MyFile.java
//-d is used to specify the directory for output java file
więc usuńmy cukier składniowy
Aby odpowiedzieć na to pytanie, utworzyłem plik i napisał dwie wersje for
each
, jeden z array
i drugi z list
. mój java
plik wyglądał tak.
import java.util.*;
public class Temp{
private static void forEachArray(){
int[] arr = new int[]{1,2,3,4,5};
for(int i: arr){
System.out.print(i);
}
}
private static void forEachList(){
List<Integer> list = Arrays.asList(1,2,3,4,5);
for(Integer i: list){
System.out.print(i);
}
}
}
Kiedy compiled
ten plik z powyższym przełącznikiem, otrzymałem następujące wyjście.
import java.util.*;
public class Temp {
public Temp() {
super();
}
private static void forEachArray() {
int[] arr = new int[]{1, 2, 3, 4, 5};
for (/*synthetic*/ int[] arr$ = arr, len$ = arr$.length, i$ = 0; i$ < len$; ++i$) {
int i = arr$[i$];
{
System.out.print(i);
}
}
}
private static void forEachList() {
List list = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4), Integer.valueOf(5)});
for (/*synthetic*/ Iterator i$ = list.iterator(); i$.hasNext(); ) {
Integer i = (Integer)i$.next();
{
System.out.print(i);
}
}
}
}
Widać, że wraz z innym cukrem składniowym (Autoboxingiem) dla każdej pętli zmieniono na proste pętle.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-17 16:01:30
To wygląda szalenie, ale hej to działa
List<String> someList = new ArrayList<>(); //has content
someList.forEach(System.out::println);
To działa. MagiaWarning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-29 08:38:51
Myślę, że to zadziała:
for (Iterator<String> i = someList.iterator(); i.hasNext(); ) {
String x = i.next();
System.out.println(x);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-26 18:09:05