В Java 8 мы можем использовать новый forEach для цикла или итерации Карты , Список , Установить , или Поток .
Темы
- Зациклить карту
- Зациклить список
- Для каждого и потребителя
- для каждого и обработки исключений
- Для каждого из них vs для каждого заказанного
1. Зациклить карту
1.1 Ниже приведен обычный способ зацикливания Карты .
public static void loopMapClassic() {
Map map = 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() {
Map map = 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() {
Map map = 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() {
Map map = 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() {
List list = 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() {
List list = 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() {
List list = 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) {
List list = 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, List files) {
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/”