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

在本页中,我们将提供Java8 FlatMap示例。我们在这里讨论Stream.flatMap以及Optional.flatMap()方法。

Stream.flatMap()返回流,该流将包含通过映射函数替换源流的每个元素而获得的元素,并展平结果。映射函数将生成流,并且在应用映射后关闭每个映射流。在对象流上应用统计函数是有用的,并且可以在一行中进行编码。

Optional.flatMap()如果存在值,则对其应用可选的方位映射函数。下面是不同场景下的flatMap示例。

在Java文档,Stream.flatMap()方法的定义如下

<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)

Optional.flatMap()的定义如下

public <U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper)

对于原始数据类型,java提供了flatMapToInt()flatMapToLong()flatMapToDouble()的接口。

1.在List中使用Stream.flatMap方法

这里我们有一份作家名单。每个作家都有一份书单。使用Stream.flatMap()我们将从所有作家那里得到所有书籍。然后我们会找到价格最高的那本书。
1.作家流对象.

{
   {"Mohan",
    {
      {10,"AAA"}, {20,"BBB"}
    }
   },
   {"Sohan",
    {
      {30,"XXX"}, {15,"ZZZ"}
    }
   }
}

2.使用flatMap(writer -> writer.getBooks().stream())方法后,得到书单的流对象。

{      
   {10,"AAA"}, 
   {20,"BBB"},
   {30,"XXX"}, 
   {15,"ZZZ"}
}

这里的结果被flatMap()方法展开。

3.使用max(new BookComparator())方法后,得到最贵的书籍。

{30,"XXX"}

下面我们来看代码

FlatmapWithList.java

package com.concretepage;
import java.util.Arrays;
import java.util.List;
public class FlatmapWithList {
    public static void main(String[] args) {
    	List<Book> books = Arrays.asList(new Book(10, "AAA"), new Book(20, "BBB"));
    	Writer w1 = new Writer("Mohan", books);
    	books = Arrays.asList(new Book(30, "XXX"), new Book(15, "ZZZ"));
    	Writer w2 = new Writer("Sohan", books);    	
    	List<Writer> writers = Arrays.asList(w1, w2);
    	Book book = writers.stream().flatMap(writer -> writer.getBooks().stream())
    			.max(new BookComparator()).get();
    	System.out.println("Name:"+book.getName()+", Price:"+ book.getPrice() );
    }
}  

Writer.java

package com.concretepage;
import java.util.List;
public class Writer {
	private String name;
	private List<Book> books;
	public Writer(String name, List<Book> books) {
		this.name = name;
		this.books = books;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List<Book> getBooks() {
		return books;
	}
	public void setBooks(List<Book> books) {
		this.books = books;
	}
} 

Book.java

package com.concretepage;
public class Book {
	private int price;
	private String name;
	public Book(int price, String name) {
		this.price = price;
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
} 

BookComparator.java

package com.concretepage;
import java.util.Comparator;
public class BookComparator implements Comparator<Book> {
	@Override
	public int compare(Book b1, Book b2) {
		if (b1.getPrice() > b2.getPrice()) {
			return 1;
		} else if (b1.getPrice() == b2.getPrice()) {
			return 0;
		} else {
			return -1;
		}
	}
} 

输出

Name:XXX, Price:30

2.在List列表中使用Stream.flatMap方法

在这里,我们将使用带有List列表的flatMap方法。我们正在创建两个列表,每个列表都包含图书的对象。最后,我将这两个列表添加到第三个列表中。我们将以最低价格买到这本书。

FlatmapWithListOfList.java

package com.concretepage;
import java.util.Arrays;
import java.util.List;
public class FlatmapWithListOfList {
    public static void main(String[] args) {
    	List<Book> list1 = Arrays.asList(new Book(10, "AAA"), new Book(20, "BBB"));
    	List<Book> list2 = Arrays.asList(new Book(30, "XXX"), new Book(15, "ZZZ"));
    	List<List<Book>> finalList = Arrays.asList(list1, list2);
    	Book book = finalList.stream().flatMap(list -> list.stream()).min(new BookComparator()).get();
    	System.out.println("Name:"+book.getName()+", Price:"+ book.getPrice() );
    }
} 

输出

Name:AAA, Price:10

3.在Array中使用Stream.flatMap方法

在这里,我们将使用带数组的flatMap。我正在用整数数据创建一个二维数组。最后我们将找出偶数。
1.数组样本

{{1,2},{3,4},{5,6}}

2.使用flatMap(row -> Arrays.stream(row))方法后

{1,2,3,4,5,6}

3.使用filter(num -> num%2 == 0)方法后

{2,4,6}

下面来看具体的代码示例

FlatMapWithArray.java

package com.concretepage;
import java.util.Arrays;
public class FlatMapWithArray {
	public static void main(String[] args) {
		Integer[][] data = {{1,2},{3,4},{5,6}};
		Arrays.stream(data).flatMap(row -> Arrays.stream(row)).filter(num -> num%2 == 0).
		forEach(System.out::println);
	}
} 

输出

2
4
6 

4.在对象数组中使用Stream.flatMap方法

这里我们将提供一个带有对象数组的flatMap示例。我们将创建Writer的二维数组。此类将包含书籍列表。我们会找到最高价的书。

FlatMapWithArrayOfObject.java

package com.concretepage;
import java.util.Arrays;
import java.util.List;
public class FlatMapWithArrayOfObject {
    public static void main(String[] args) {
    	List<Book> books = Arrays.asList(new Book(10, "AAA"), new Book(20, "BBB"));
    	Writer w1 = new Writer("Mohan", books);
    	books = Arrays.asList(new Book(30, "CCC"), new Book(15, "DDD"));
    	Writer w2 = new Writer("Sohan", books);    	
    	books = Arrays.asList(new Book(45, "EEE"), new Book(25, "FFF"));
    	Writer w3 = new Writer("Vikas", books);
    	books = Arrays.asList(new Book(5, "GGG"), new Book(15, "HHH"));
    	Writer w4 = new Writer("Ramesh", books);
        Writer[][] writerArray = {{w1,w2},{w3,w4}};
        
        Book book = Arrays.stream(writerArray).flatMap(row -> Arrays.stream(row)).
            flatMap(writer -> writer.getBooks().stream()).max(new BookComparator()).get();
        
        System.out.println("Name:"+book.getName()+", Price:"+ book.getPrice() );
    }
} 

输出

Name:EEE, Price:45

5.Files.lines()中使用Stream.flatMap方法

Files.lines()已在Java8中引入。它以流的形式读取文件的所有行。在我们的示例中,我们有一个包含一些行的文件。我们将把所有单词存储在一个列表中并打印出来。

info.txt

My name is Mohan
Country is India  

FlatMapWithFile.java

package com.concretepage;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class FlatMapWithFile {
	public static void main(String[] args) {
	    Stream<String> lines = null;
	    try {
		lines = Files.lines(Paths.get("D:/cp/info.txt"), StandardCharsets.UTF_8);
	    } catch (IOException e) {
		e.printStackTrace();
	    }
	    Stream<String> stream = lines.flatMap(line -> Stream.of(line.split(" +")));
	    List<String> words = new ArrayList<>();
	    stream.forEach(w->words.add(w));
	    words.forEach(w -> System.out.println(w));
	}
} 

输出

My
name
is
Mohan
Country
is
India 

6.Optional flatMap

java8中引入了Optional。它的行为类似于一个可以保持非空值的容器。它处理NullPointerExceptionflatMap仅当值存在时才应用。找一个例子。

OptionalflatMap.java

package com.concretepage;
import java.util.Optional;
public class OptionalflatMap {
    public static void main(String[] args) {
        Optional<PrimeMinister> primeMinister = Optional.of(new PrimeMinister("Narendra Modi", 65));
        Optional<Country> country = Optional.of(new Country(primeMinister));
        Optional<Person> person = Optional.of(new Person(country));
        String pmName= person.flatMap(Person::getCountry).flatMap(Country::getPrimeMinister)
                .map(PrimeMinister::getName).orElse("None");
        System.out.println(pmName);
   }
} 

Country.java

package com.concretepage;
import java.util.Optional;
public class Country {
	Optional<PrimeMinister> primeMinister;
        public Country(){}
        public Country(Optional<PrimeMinister> primeMinister){
                this.primeMinister = primeMinister;
        }
	public Optional<PrimeMinister> getPrimeMinister() {
		return primeMinister;
	}
	public void setPrimeMinister(Optional<PrimeMinister> primeMinister) {
		this.primeMinister = primeMinister;
	}
} 

Person.java

package com.concretepage;
import java.util.Optional;
public class Person {
	Optional<Country> country;
        public Person(){}
        public Person(Optional<Country> country){
        this.country = country;
        }
	public Optional<Country> getCountry() {
		return country;
	}
	public void setCountry(Optional<Country> country) {
		this.country = country;
	}
} 

输出

Narendra Modi

代码下载

java-8-flatmap-example.zip

参考文献

【1】Java 8 flatMap Example

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫巳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值