【Java 8 新特性】Java forEach使用示例

  • 1.在`Iterable`中使用`forEach()`方法
  • 2.在`Map`中使用`forEach()`方法
  • 3.在`Stream`中使用`forEach()`方法
  • 4.在`List`中使用的示例
  • 5.在`Set`中使用的示例
  • 6.在`Queue`中使用的示例
  • 7.在`DirectoryStream`中使用的示例
  • 8.在`Path`中使用的示例
  • 9.在`Map`中使用的示例
  • 10.在`Stream`中使用的示例
  • 11.参考文献

forEach方法迭代源元素并执行给定的操作。

在Java8中,Iterable接口引入forEach作为默认方法,接受该函数作为ConsumerMap接口也引入forEach作为默认方法,接受该函数作为BiConsumer

在Java8中,Stream也有forEach方法,接受该函数作为Consumer

Iterable接口由Collection扩展,因此forEach方法可用于ListSetQueue等。

在这一页,我们将提供使用forEach方法的详细例子

1.在Iterable中使用forEach()方法

这个java.lang.Iterable接口在Java8中引入了forEach默认方法,如下所示。

default void forEach(Consumer<? super T> action)

作用:作为Consumer对每个元素执行的操作。

上面的forEach方法对Iterable的每个元素执行给定的操作。

forEach将因所有元素已被处理或操作引发异常而停止。

forEach按照迭代的顺序执行操作。

Iterable通过以下接口进行扩展。

(a) java.util.Collection:我们可以使用forEach方法来处理ListSetQueue等。
(b ) java.nio.file.DirectoryStream:我们可以将forEach方法与DirectoryStream一起使用,DirectoryStream是一个在目录中迭代条目的对象。要实例化DirectoryStream,请使用Files.newDirectoryStream()方法。
(c ) java.nio.file.Path:我们可以将forEach方法与Path一起使用,Path是一个用于在文件系统中定位文件的对象。要实例化Path,请使用Paths.get()方法。

2.在Map中使用forEach()方法

这个java.util.Map接口在Java8中引入了forEach默认方法,如下所示。

default void forEach(BiConsumer<? super K,? super V> action)

作用:作为BiConsumer对每个条目执行的操作。

上面的forEach方法对Map的每个条目执行给定的操作。forEach将因所有条目已处理或操作引发异常而停止。forEach按照入口集迭代的顺序执行操作。

我们可以将forEach方法用于Map的所有实现类,如HashMapLinkedHashMapTreeMapConcurrentHashMap等。

3.在Stream中使用forEach()方法

a. forEach from java.util.stream.Stream.

void forEach(Consumer<? super T> action)

作为此Stream的每个元素的Consumer执行给定的操作。

b. forEach from java.util.stream.IntStream.

void forEach(IntConsumer action)

作为此IntStream的每个元素的IntConsumer执行给定的操作。

c. forEach from java.util.stream.LongStream.

void forEach(LongConsumer action)

作为此LongStream的每个元素的LongConsumer执行给定的操作。

d. forEach from java.util.stream.DoubleStream.

void forEach(DoubleConsumer action)

作为此DoubleStream的每个元素的DoubleConsumer执行给定的操作。

4.在List中使用的示例

使用List.forEach方法,我们需要将Consumer作为操作传递。我们可以将Consumer作为lambda表达式或方法引用传递。

下面是lambda表达式的示例

List<String> techList = Arrays.asList("Java", "Spring", "Oracle");
techList.forEach(s -> System.out.println(s));

下面是方法引用的示例

techList.forEach(System.out::println);

输出

Java
Spring
Oracle

再找一个 forEach方法的例子。这里有一个对象列表。

ForEachDemoWithList.java

package com.concretepage;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class ForEachDemoWithList {
  public static void main(String[] args) {
	List<Student> list = new ArrayList<>();
	list.add(new Student("Ram", "male"));
	list.add(new Student("Meera", "female"));
	list.add(new Student("Kabir", "male"));

	System.out.println("---Using lambda expression---");
	Consumer<Student> maleStds = (Student s) -> {
	  if ("male".equals(s.getGender())) {
		System.out.print(s.getName() + " ");
	  }
	};

	list.forEach(maleStds);

	System.out.println("\n---Using method reference---");
	list.forEach(Student::printMaleStds);
  }
}
class Student {
  private String name;
  private String gender;
  public Student(String name, String gender) {
	this.name = name;
	this.gender = gender;
  }
  public void printMaleStds() {
	if ("male".equals(getGender())) {
	  System.out.print(getName() +" ");
	}
  }
  //Sets and Gets
}

输出

---Using lambda expression---
Ram Kabir 
---Using method reference---
Ram Kabir

5.在Set中使用的示例

使用Set.forEach方法,则需要将Consumer作为lambda表达式或方法引用传递。

创建一个Set

Set<Integer> set = new HashSet<>();
set.add(15); 
set.add(10);
set.add(20);

使用带有lambda表达式的forEach来打印数据。

set.forEach(s -> System.out.println(s));

使用方法引用

set.forEach(System.out::println);

再找一个在Set使用forEach的例子。

ForEachDemoWithSet.java

package com.concretepage;
import java.util.HashSet;
import java.util.Set;
public class ForEachDemoWithSet {
  public static void main(String[] args) {
	Set<Book> books = new HashSet<>();
	books.add(new Book("Book A", 60));
	books.add(new Book("Book B", 30));
	books.add(new Book("Book C", 40));

	// With lambda expression
	books.forEach(b -> {
	  if (b.getPrice() < 50) {
		System.out.println(b.getName());
	  }
	}); //Output: Book B, Book C
	
	// With method reference
	books.forEach(Book::printBook); //Output: Book B, Book C
  }
}
class Book {
  private String name;
  private int price;
  public Book(String name, int price) {
	this.name = name;
	this.price = price;
  }
  public void printBook() {
	if (price < 50) {
	  System.out.println(name);
	}
  }
  //Sets, Gets, equals, hashCode
}

6.在Queue中使用的示例

使用Queue.forEach方法,则需要将Consumer作为lambda表达式或方法引用传递。

下面是forEachQueue的示例。我们在这里用它的实现类ArrayDeque实例化队列。

ForEachDemoWithQueue.java

package com.concretepage;
import java.util.ArrayDeque;
public class ForEachDemoWithQueue {
  public static void main(String[] args) {
	ArrayDeque<String> queue = new ArrayDeque<String>();
	queue.add("BB");
	queue.add("CC");

	queue.offerFirst("AA");
	queue.offerLast("DD");

	// With lambda expression
	queue.forEach(e -> System.out.println(e)); //AA, BB, CC, DD

	// With method reference
	queue.forEach(System.out::println); //AA, BB, CC, DD
  }
}

7.在DirectoryStream中使用的示例

使用DirectoryStream.forEach方法,则需要将Consumer作为lambda表达式或方法引用传递。

下面是使用lambda表达式的DirectoryStreamforEach示例。

WithDirectoryStream.java

package com.concretepage;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class WithDirectoryStream {
  public static void main(String[] args) throws IOException {
	  Path dir = Paths.get("C:/page");
	  DirectoryStream<Path> dirStream = Files.newDirectoryStream(dir, "*.{txt,jpg}");

	  dirStream.forEach(f -> System.out.println(f.getFileName()));
  }
}

8.在Path中使用的示例

使用Path.forEach方法,则需要将Consumer作为lambda表达式或方法引用传递。

下面是使用lambda表达式的PathforEach示例。

ForEachDemoWithPath.java

package com.concretepage;
import java.nio.file.Path;
import java.nio.file.Paths;
public class ForEachDemoWithPath {
  public static void main(String[] args) {
	  Path dir = Paths.get("C:/page/java/java8/myclass.java");
	  dir.forEach(f -> System.out.println(f.getFileName()));
  }
}

9.在Map中使用的示例

使用Map.forEach方法,则需要将BiConsumer作为lambda表达式或方法引用传递。

假设我们有下面的Map

Map<Integer, String> map = new HashMap<>();
map.put(101, "Java");
map.put(102, "Angular");
map.put(103, "Spring");

下面是forEachMap中的迭代示例

map.forEach((k, v) -> System.out.println(k + "-" + v));

我们将得到以下输出。

101-Java
102-Angular
103-Spring

再找一个forEachMap中使用的例子。

ForEachDemoWithMap.java

package com.concretepage;
import java.util.HashMap;
import java.util.Map;
public class ForEachDemoWithMap {
  public static void main(String[] args) {
	Map<Integer, User> map = new HashMap<>();
	map.put(101, new User("Mahesh", true));
	map.put(102, new User("Suresh", false));
	map.put(103, new User("Krishn", true));

	System.out.println("---Passing BiConsumer as lambda expression---");
	map.forEach((k, v) -> {
	  if (v.isActive() == true) {
		System.out.println(k + " - " + v.getUserName());
	  }
	});

	System.out.println("---Passing BiConsumer as method reference---");
	map.forEach(User::printActiveUser);
  }
}
class User {
  private String userName;
  private boolean active;

  public User(String userName, boolean active) {
	this.userName = userName;
	this.active = active;
  }
  public static void printActiveUser(int id, User user) {
	if (user.isActive() == true) {
	  System.out.println(id + " - " + user.getUserName());
	}
  }
  //Sets and Gets
}

输出

---Passing BiConsumer as lambda expression---
101 - Mahesh
103 - Krishn
---Passing BiConsumer as method reference---
101 - Mahesh
103 - Krishn

10.在Stream中使用的示例

使用Stream.forEach方法,则需要将Consumer作为lambda表达式或方法引用传递。

ForEachDemoWithStream1.java

package com.concretepage;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class ForEachDemoWithStream1 {
  public static void main(String[] args) {
	Stream<String> stream = Stream.of("Mahesh", "Nilesh", "Mohit");
	stream.forEach(e -> System.out.println(e)); //Mahesh, Nilesh, Mohit

	List<String> list = Arrays.asList("Mahesh", "Nilesh", "Mohit");
	list.stream().filter(e -> e.startsWith("M")).forEach(e -> System.out.println(e)); //Mahesh, Mohit
	
	list.stream().filter(e -> e.startsWith("M")).forEach(System.out::println); //Mahesh, Mohit
	
	list.stream().sorted().forEach(e -> System.out.println(e)); //Mahesh, Mohit, Nilesh
  }
}

IntStream通过IntConsumerLongStream通过LongConsumerDoubleStream通过DoubleConsumer来使用forEach方法。

下面来看示例

ForEachDemoWithStream2.java

package com.concretepage;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
public class ForEachDemoWithStream2 {
  public static void main(String[] args) {
    // With IntStream
    IntStream.of(30, 40, 50).forEach(s -> System.out.println(s)); //30, 40, 50
    IntStream.of(30, 40, 50).forEach(System.out::println); //30, 40, 50
	
    IntStream.of(30, 40, 50).flatMap(e -> IntStream.of(e / 10))
	    .forEach(e -> System.out.println(e)); //3, 4, 5

    // With LongStream	
    LongStream.of(300, 400, 500).forEach(s -> System.out.println(s)); //300, 400, 500
    LongStream.of(300, 400, 500).forEach(System.out::println); //300, 400, 500
	
    LongStream.of(300, 400, 500).flatMap(e -> LongStream.of(e / 100))
	    .forEach(e -> System.out.println(e)); //3, 4, 5
	
    // With DoubleStream
    DoubleStream.of(30.15, 40.35, 50.55).forEach(s -> System.out.println(s)); //30.15, 40.35, 50.55
    DoubleStream.of(30.15, 40.35, 50.55).forEach(System.out::println); //30.15, 40.35, 50.55
	
    DoubleStream.of(30.15, 40.35, 50.55).flatMap(e -> DoubleStream.of(e * 10))
	    .forEach(e -> System.out.println(e)); //301.5, 403.5, 505.5    
  }
}

11.参考文献

【1】Java doc: Iterable【2】Java doc: Map【3】Java doc: Stream【4】Java forEach() Example