В Java 8 мы можем использовать новый forEach
для цикла или итерации Карты
, Список
, Установить
, или Поток
.
Темы
- Зациклить карту
- Зациклить список
- Для каждого и потребителя
- для каждого и обработки исключений
- Для каждого из них vs для каждого заказанного
1. Зациклить карту
1.1 Ниже приведен обычный способ зацикливания Карты
.
public static void loopMapClassic() { Mapmap = new HashMap<>(); map.put("A", 10); map.put("B", 20); map.put("C", 30); map.put("D", 40); map.put("E", 50); map.put("F", 60); for (Map.Entry entry : map.entrySet()) { System.out.println("Key : " + entry.getKey() + ", Value : " + entry.getValue()); } }
1.2 В Java 8 мы можем использовать forEach
для выполнения цикла Карта
и распечатайте его записи.
public static void loopMapJava8() { Mapmap = new HashMap<>(); map.put("A", 10); map.put("B", 20); map.put("C", 30); map.put("D", 40); map.put("E", 50); map.put("F", 60); // lambda map.forEach((k, v) -> System.out.println("Key : " + k + ", Value : " + v)); }
Выход
Key : A, Value : 10 Key : B, Value : 20 Key : C, Value : 30 Key : D, Value : 40 Key : E, Value : 50 Key : F, Value : 60
1.3 Для ключа карты
или значения, содержащего null
, Для каждого
будет выведено null
.
public static void loopMapJava8() { Mapmap = new HashMap<>(); map.put("A", 10); map.put("B", 20); map.put("C", 30); map.put(null, 40); map.put("E", null); map.put("F", 60); // ensure map is not null if (map != null) { map.forEach((k, v) -> System.out.println("Key : " + k + ", Value : " + v)); } }
Выход
Key : null, Value : 40 Key : A, Value : 10 Key : B, Value : 20 Key : C, Value : 30 Key : E, Value : null Key : F, Value : 60
P.S Обычный способ зацикливания a Карта выведет тот же результат, что и выше.
1.4 Если мы не хотим печатать ключ null
, добавьте простую проверку на нуль внутри forEach
.
public static void loopMapJava8() { Mapmap = new HashMap<>(); map.put("A", 10); map.put("B", 20); map.put("C", 30); map.put(null, 40); map.put("E", null); map.put("F", 60); map.forEach( (k, v) -> { // yes, we can put logic here if (k != null){ System.out.println("Key : " + k + ", Value : " + v); } } ); }
Выход
Key : A, Value : 10 Key : B, Value : 20 Key : C, Value : 30 Key : E, Value : null Key : F, Value : 60
2. Зациклить список
2.1 Ниже приведен обычный способ зацикливания списка
.
public static void loopListClassic() { Listlist = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); list.add("D"); list.add("E"); // normal loop for (String l : list) { System.out.println(l); } }
2.2 Java 8 Для каждого
для создания цикла Списка
.
public static void loopListJava8() { Listlist = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); list.add("D"); list.add("E"); // lambda // list.forEach(x -> System.out.println(x)); // method reference list.forEach(System.out::println); }
Выход
A B C D E
2.3 В этом примере выполняется фильтрация нулевого значения списка
.
public static void loopListJava8() { Listlist = new ArrayList<>(); list.add("A"); list.add("B"); list.add(null); list.add("D"); list.add("E"); // filter null value list.stream() .filter(Objects::nonNull) .forEach(System.out::println); }
Выход
A B D E
P.S То инструкция foreach для Набор и Течение работает точно так же.
3. Для каждого и потребителя
3.1 Просмотрите сигнатуру метода forEach
, он принимает функциональный интерфейс Потребитель .
public interface Iterable{ default void forEach(Consumer super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } //.. }
public interface Streamextends BaseStream > { void forEach(Consumer super T> action); //... }
3.2 В этом примере создается метод Consumer
для печати строки в шестнадцатеричном формате. Теперь мы можем повторно использовать то же самое Потребитель
метод и передайте его в Для каждого
метода Списка
и Поток
.
package com.mkyong.java8.misc; import java.util.*; import java.util.function.Consumer; import java.util.stream.Stream; public class ForEachConsumer { public static void main(String[] args) { Listlist = Arrays.asList("abc", "java", "python"); Stream stream = Stream.of("abc", "java", "python"); // convert a String to a Hex Consumer printTextInHexConsumer = (String x) -> { StringBuilder sb = new StringBuilder(); for (char c : x.toCharArray()) { String hex = Integer.toHexString(c); sb.append(hex); } System.out.print(String.format("%n%-10s:%s", x, sb.toString())); }; // pass a Consumer list.forEach(printTextInHexConsumer); stream.forEach(printTextInHexConsumer); } }
Выход
abc :616263 java :6a617661 python :707974686f6e abc :616263 java :6a617661 python :707974686f6e
4. для каждого и обработки исключений.
4.1 forEach
предназначен не только для печати, и в этом примере показано, как использовать метод forEach
для зацикливания списка объектов и записи его в файлы.
package com.mkyong.java8.misc; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.List; public class ForEachWriteFile { public static void main(String[] args) { ForEachWriteFile obj = new ForEachWriteFile(); obj.save(Paths.get("C:\\test"), obj.createDummyFiles()); } public void save(Path path, Listfiles) { if (!Files.isDirectory(path)) { throw new IllegalArgumentException("Path must be a directory"); } files.forEach(f -> { try { int id = f.getId(); // create a filename String fileName = id + ".txt"; Files.write(path.resolve(fileName), f.getContent().getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { e.printStackTrace(); } }); } public List createDummyFiles() { return Arrays.asList( new DummyFile(1, "hello"), new DummyFile(2, "world"), new DummyFile(3, "java")); } class DummyFile { int id; String content; public DummyFile(int id, String content) { this.id = id; this.content = content; } public int getId() { return id; } public String getContent() { return content; } } }
Вышеуказанная программа создаст три текстовых файла.
hello
world
java
4.2 Files.write
может вызвать Исключение IOException
, и мы должны поймать исключение внутри foreach
; таким образом, код выглядит уродливо. Обычной практикой является извлечение кода в новый метод.
public void save(Path path, Listfiles) { if (!Files.isDirectory(path)) { throw new IllegalArgumentException("Path must be a directory"); } // extract it to a new method /*files.forEach(f -> { try { int id = f.getId(); // create a filename String fileName = id + ".txt"; Files.write(path.resolve(fileName), f.getContent().getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { e.printStackTrace(); } });*/ // nice! files.forEach(f -> saveFile(path, f)); } public void saveFile(Path path, DummyFile f) { try { int id = f.getId(); // create a filename String fileName = id + ".txt"; Files.write(path.resolve(fileName), f.getContent().getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { e.printStackTrace(); } }
Теперь мы также можем писать такой код:
ForEachWriteFile obj = new ForEachWriteFile(); Path path = Paths.get("C:\\test"); obj.createDummyFiles().forEach(o -> obj.saveFile(path, o));
5. Для каждого из них vs для каждого заказанного
5.1 forEach
не гарантирует порядок встреч потока, независимо от того, является ли поток последовательным или параллельным. Результат очевиден при запуске в параллельном режиме.
Streams = Stream.of("a", "b", "c", "1", "2", "3"); s.parallel().forEach(x -> System.out.println(x));
Каждый запуск приведет к другому результату:
1 2 b c 3 a
5.2 Предварительно упорядоченный
гарантирует порядок встреч потока; таким образом, он жертвует преимуществом параллелизма.
Streams = Stream.of("a", "b", "c", "1", "2", "3"); // keep order, it is always a,b,c,1,2,3 s.parallel().forEachOrdered(x -> System.out.println(x));
Результат всегда a, b, c, 1, 2, 3
a b c 1 2 3
Скачать Исходный Код
$клон git $клон git
$компакт-диск java8
Рекомендации
- Потребительский JavaDoc
- Для каждого JavaDoc
- Примеры потребителей Java 8
- Преобразование шестнадцатеричного кода в ASCII на Java
Оригинал: “https://mkyong.com/java8/java-8-foreach-examples/”