Stream

import static java.util.stream.Collectors.toList;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.IntSupplier;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import org.junit.Test;
/**
 * @author Andypan
 * @StraemTest.java
 * @{describe}
 * @date 2017年8月8日 上午11:08:33
 */
public class StreamTest
{
/**
       你可以使用filter、distinct、skip和limit对流做筛选和切片。
 你可以使用map和flatMap提取或转换流中的元素。
 你可以使用findFirst 和findAny 方法查找流中的元素。你可以用allMatch 、
      noneMatch和anyMatch方法让流匹配给定的谓词。
 这些方法都利用了短路:找到结果就立即停止计算;没有必要处理整个流。
 你可以利用reduce方法将流中所有的元素迭代合并成一个结果,例如求和或查找最大
               元素。
 filter和map等操作是无状态的,它们并不存储任何状态。reduce等操作要存储状态才
能计算出一个值。sorted和distinct等操作也要存储状态,因为它们需要把流中的所
有元素缓存起来才能返回一个新的流。这种操作称为有状态操作。
 流有三种基本的原始类型特化:IntStream、DoubleStream和LongStream。它们的操
作也有相应的特化。
 流不仅可以从集合创建,也可从值、数组、文件以及iterate与generate等特定方法
创建。
 无限流是没有固定大小的流。
*/
private static List<Transaction> transactions;
static
{
Trader raoul = new Trader("Raoul", "Cambridge");
Trader mario = new Trader("Mario", "Milan");
Trader alan = new Trader("Alan", "Cambridge");
Trader brian = new Trader("Brian", "Cambridge");
transactions = Arrays.asList(new Transaction(brian, 2011, 300), new Transaction(raoul, 2012, 1000),
new Transaction(raoul, 2011, 400), new Transaction(mario, 2012, 710), new Transaction(mario, 2012, 700),
new Transaction(alan, 2012, 950));
}

一个大大的彩蛋https://mp.csdn.net/postedit/82686446


public static void main(String[] args)
{


// (1) 找出2011年发生的所有交易,并按交易额排序(从低到高)。
transactions.stream().filter(e -> e.getYear() == 2011).sorted(Comparator.comparing(Transaction::getValue))
.collect(toList()).forEach(System.out::println);


// (2) 交易员都在哪些不同的城市工作过?
transactions.stream().map(e -> e.getTrader().getCity()).distinct().collect(toList())
// 或者你可以去掉distinct(),改用toSet()
// transactions.stream().map(e ->
// e.getTrader().getCity()).collect(toS())
.forEach(System.out::println);


// (3) 查找所有来自于剑桥的交易员,并按姓名排序。
transactions.stream().map(e -> e.getTrader()).filter(e -> e.getCity().equals("Cambridge")).distinct()
.sorted(Comparator.comparing(Trader::getName)).collect(toList()).forEach(System.out::println);


// (4) 返回所有交易员的姓名字符串,按字母顺序排序。
transactions.stream().map(Transaction::getTrader).map(Trader::getName).distinct().sorted().collect(toList())
.forEach(System.out::println);


// not efficient!
String names = transactions.stream().map(Transaction::getTrader).map(Trader::getName).distinct().sorted()
.reduce("", (n1, n2) -> n1 + n2);


String names2 = transactions.stream().map(Transaction::getTrader).map(Trader::getName).distinct().sorted()
.collect(Collectors.joining(","));
System.out.println(names2);


// (5) 有没有交易员是在米兰工作
boolean existMilan = transactions.stream().anyMatch(e -> e.getTrader().getCity().equals("Milan"));
System.out.println(existMilan);
// (6) 打印生活在剑桥的交易员的所有交易额。
transactions.stream().filter(e -> e.getTrader().getCity().equals("Cambridge")).map(Transaction::getValue)
.forEach(System.out::println);
// (7) 所有交易中,最高的交易额是多少?
int max = transactions.stream().map(Transaction::getValue).reduce(Integer::max).get();
System.out.println(max);
// (8) 找到交易额最小的交易。
// int min1 =
// transactions.stream().map(Transaction::getValue).reduce(Integer::min).get();
int min2 = transactions.stream().min(Comparator.comparing(Transaction::getValue)).get().getValue();
System.out.println(min2);


}


@Test
public void numberStreamTest()
{
// 映射到数值流(avoid boxing and unboxing)
transactions.stream().mapToInt(Transaction::getValue).sum();
transactions.stream().mapToInt(Transaction::getValue).max().getAsInt();
transactions.stream().mapToInt(Transaction::getValue).average();


IntStream intStream = transactions.stream().mapToInt(Transaction::getValue);
// 转换回对象流
Stream<Integer> stream = intStream.boxed();


IntStream evenNumbers = IntStream.rangeClosed(1, 100).filter(n -> n % 2 == 0);
System.out.println(evenNumbers.count());


// 100以内的勾股数
Stream<int[]> pythagoreanTriples = IntStream.rangeClosed(1, 100).boxed()
.flatMap(a -> IntStream.rangeClosed(a, 100).filter(b -> Math.sqrt(a * a + b * b) % 1 == 0)
.mapToObj(b -> new int[] { a, b, (int) Math.sqrt(a * a + b * b) }));
pythagoreanTriples.limit(5).forEach(t -> System.out.println(t[0] + ", " + t[1] + ", " + t[2]));
}


@Test
public void buildStreamTest()
{


// (1)由值创建流
Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action");
stream.map(String::toUpperCase).forEach(System.out::println);
// 你可以使用empty得到一个空流
Stream<String> emptyStream = Stream.empty();


// (2)由数组创建流
int[] numbers = { 2, 3, 5, 7, 11, 13 };
int sum = Arrays.stream(numbers).sum();


// (3)由文件生成流
// 用这个方法看看一个文件中有多少各不相同的词
// 你可以使用Files.lines得到一个流,其中的每个元素都是给定文件中的一行。然后,你
// 可以对line调用split方法将行拆分成单词。应该注意的是,你该如何使用flatMap产生一个扁
// 平的单词流,而不是给每一行生成一个单词流。最后,把distinct和count方法链接起来,数
// 数流中有多少各不相同的单词。
long uniqueWords = 0;
try (Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset()))
{
uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" "))).distinct().count();
} catch (IOException e)
{
}


// (4)由函数生成流:创建无限流


// 1,迭代 iterate
Stream.iterate(0, n -> n + 2).limit(10).forEach(System.out::println);


// 斐波那契数列
Stream.iterate(new int[] { 0, 1 }, t -> new int[] { t[1], t[0] + t[1] }).limit(20)
.forEach(t -> System.out.println("(" + t[0] + "," + t[1] + ")"));


// 2,generate
Stream.generate(Math::random).limit(5).forEach(System.out::println);


// 下面的代码就是如何创建一个在调用时返回下一个斐波纳契项的IntSupplier:
IntSupplier fib = new IntSupplier() {
private int previous = 0;
private int current = 1;


public int getAsInt()
{
int oldPrevious = this.previous;
int nextValue = this.previous + this.current;
this.previous = this.current;
this.current = nextValue;
return oldPrevious;
}
};
IntStream.generate(fib).limit(10).forEach(System.out::println);
}

@Test
public void flatMapTest(){
String[] arrayOfWords = { "Goodbye", "World" };
Stream<String> streamOfwords = Arrays.stream(arrayOfWords);
streamOfwords.map(word -> word.split("")) //将每个单词转换为由其字母构成的数组
.flatMap(Arrays::stream)//将各个生成流扁平化为单个流
.distinct()
.collect(toList())
.forEach(System.out::println);
//使用flatMap方法的效果是,各个数组并不是分别映射成一个流,而是映射成流的内容。所
//有使用map(Arrays::stream)时生成的单个流都被合并起来,即扁平化为一个流。
//一言以蔽之,flatmap方法让你把一个流中的每个值都换成另一个流,然后把所有的流连接
//起来成为一个流。

List<Integer> numbers1 = Arrays.asList(1, 2, 3);
List<Integer> numbers2 = Arrays.asList(3, 4); 
//List<int[]> pairs =
numbers1.stream()
.flatMap(i -> numbers2.stream().map(j -> new int[]{i, j}))
.collect(toList()).forEach(e -> System.out.println(""+e[0]+" "+e[1]));
System.out.println("----------------");

numbers1.stream()
.flatMap(i -> numbers2.stream().filter(j -> (i+j) % 3 == 0).map(j -> new int[]{i,j})).
forEach(e -> System.out.println(""+e[0]+" "+e[1]));
}
}


class Trader
{
private final String name;
private final String city;


public Trader(String n, String c) {
this.name = n;
this.city = c;
}


public String getName()
{
return this.name;
}


public String getCity()
{
return this.city;
}


/*
* (non-Javadoc)

* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
return "Trader [name=" + name + ", city=" + city + "]";
}


}


class Transaction
{
private final Trader trader;
private final int year;
private final int value;


public Transaction(Trader trader, int year, int value) {
this.trader = trader;
this.year = year;
this.value = value;
}


public Trader getTrader()
{
return this.trader;
}


public int getYear()
{
return this.year;
}


public int getValue()
{
return this.value;
}


public String toString()
{
return "{" + this.trader + ", " + "year: " + this.year + ", " + "value:" + this.value + "}";
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值