1. 程式人生 > >Java8之stream實戰

Java8之stream實戰

        最近並沒有放下學網際網路架構的框架,但是也用更多的時間去看Java8實戰。最近一兩個星期京東搞活動,來來去去買了三次書,買了9本,哈哈哈。其中有兩本是關於Java程式設計的,一本是Java的程式設計思想(還沒看),一本就是現在一到週末就看的Java8 In Action。因為學的框架越來越多,深有體會在某些業務場景他們真的很牛逼,但是說到底,我還是覺得程式設計的基礎和程式設計的思想是最重要的,框架其實就等於工具,造他們的還不是語言。而且,公司的專案都用到了Java8,但是它的特性我竟然是一次都沒用過,自從看了書之後,好想將自己以前的程式碼好好改進一番。。。

        關於Java8的新特性,我現在學到的是Lambda表示式和Stream流,這兩玩意可謂是想當的好使啊,程式碼變得想當的簡潔和健壯,而且操作起集合來簡直就是得心應手,簡簡單單一行程式碼頂以前的幾十行。

練習:

        下面是Java8 in Action學習玩Stream後的練習,挺好玩的,下面我就貼出來唄。領域:執行交易的交易員。經理讓你為八個查詢找到答案。

1、找出2011年發生的所有交易,並按交易金額排序(從低到高)

2、交易員都在哪些不同的城市工作?

3、查詢所有來自於劍橋的交易員,並按姓名排序

4、返回所有交易員姓名的字串,按字母順序排序

5、有沒有交易員是在米蘭工作的?

6、列印生活在劍橋的交易員的所有交易額

7、所有交易中,最高交易額是多少

8、找到交易額最小的交易

領域:交易員和交易

下面是你要處理的領域,一個Trader和一個Transactions列表

//交易員
Trader raoul  = new Trader("raoul","Cambridge");
Trader mario  = new Trader("mario","Milan");
Trader alan  = new Trader("alan","Cambridge");
Trader brian  = new Trader("brian","Cambridge");

//交易記錄
List<Transaction> 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));

Trader和Transaction類的定義如下:

public class Trader {
	private final String name;
	private final String city;
	
	public Trader(String name, String city) {
		super();
		this.name = name;
		this.city = city;
	}
	public String getName() {
		return name;
	}
	public String getCity() {
		return city;
	}
	@Override
	public String toString() {
		return "Trader [name=" + name + ", city=" + city + "]";
	}
}
public class Transaction {
	private final Trader trader;
	private final int year;
	private final int value;
	
	public Transaction(Trader trader, int year, int value) {
		super();
		this.trader = trader;
		this.year = year;
		this.value = value;
	}

	public Trader getTrader() {
		return trader;
	}

	public int getYear() {
		return year;
	}

	public int getValue() {
		return value;
	}

	@Override
	public String toString() {
		return "Transaction [trader=" + trader + ", year=" + year + ", value=" + value + "]";
	}
}

想自己嘗試一下的小夥伴可以先嚐試,不想嘗試的可以瞄瞄我做得咋樣。

俺的練習:註解為我自己思考的過程

public class TestDemo {
	//交易員
	Trader raoul  = new Trader("raoul","Cambridge");
	Trader mario  = new Trader("mario","Milan");
	Trader alan  = new Trader("alan","Cambridge");
	Trader brian  = new Trader("brian","Cambridge");
	//交易記錄
	List<Transaction> 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));
	
	
	//找出2011年發生的所有交易,並按交易額排序(從低到高)
	@Test
	public void test1(){
		
		//Comparator.comparing預設是升序
		List<Transaction> result = transactions.stream()
				.filter( (t)->t.getYear()==2011)//濾掉year不為2011
				.sorted(Comparator.comparing(Transaction::getValue))//根據value排序
				.collect(Collectors.toList()); 
		result.forEach(System.out::println);
	}
	
	//交易員都在哪些不同的城市工作過
	@Test
	public void test2(){
		
		List<String> result = transactions.stream()
				.map(Transaction::getTrader)//從交易記錄中映射出交易員
				.map(Trader::getCity)//從交易員映射出城市名
				.distinct()//再去重
				.collect(Collectors.toList());
		result.forEach(System.out::println);
	}
	
	//查找出所有來自劍橋的交易員,並按姓名排序
	@Test
	public void test3(){
		List<Trader> result = transactions.stream()
				.map(Transaction::getTrader)//映射出交易員
				.filter((t)->("Cambridge").equals(t.getCity()))//過濾城市為劍橋的交易員
				.distinct()//去重
				.sorted(Comparator.comparing(Trader::getName))//根據姓名排序
				.collect(Collectors.toList());
		result.forEach(System.out::println);
	}
	
	//返回所有交易員的姓名字串,按字母順序排序
	@Test
	public void test4(){
		String allName = transactions.stream()
				.map((t)->t.getTrader().getName())//映射出交易員名字
				.sorted() //排序(預設升序)
				.reduce("",(a,b)->a+b);  //如果不加"",返回的是Option<String>,因為防止源是空的
		System.out.println(allName);
	}
	
	//有沒有交易員在米蘭工作過
	@Test
	public void test5(){
		boolean flag = transactions.stream()
				.map(Transaction::getTrader)//映射出交易員
				.anyMatch(t->t.getCity().equals("Milan"));//進行匹配
		System.out.println("有沒有在米蘭工作的交易員:"+flag);
	}
	
	//列印生活在劍橋的交易員的所有交易額  2650
	@Test
	public void test6(){
		Integer sum = transactions.stream()
				.filter(t->t.getTrader().getCity().equals("Cambridge"))//過濾生活在劍橋的交易員
				.map(Transaction::getValue)//映射出交易額
				.reduce(0, (a,b)->a+b);//最後進行處理
		System.out.println("生活在劍橋的交易員的所有交易額:"+sum);
	}
	
	//所有交易中,最高的交易額是多少
	@Test
	public void test7(){
		//一開始自己的做法
		List<Integer> list = transactions.stream().sorted(Comparator.comparing(Transaction::getValue).reversed()).map(Transaction::getValue).limit(1).collect(Collectors.toList());
		System.out.println("所有交易中,最高的交易額是"+list.get(0));
		//升級1
		Optional<Integer> max = transactions.stream().map(Transaction::getValue).reduce(Integer::max);
		System.out.println("所有交易中,最高的交易額是"+max.get());
		
		//升級2
		Optional<Transaction> max2 = transactions.stream().max(Comparator.comparing(Transaction::getValue));
		System.out.println("所有交易中,最高的交易額是"+max2.get().getValue());
	}
	
	//找到交易額最小的交易
	@Test
	public void test8(){
		Optional<Integer> min = transactions.stream().map(Transaction::getValue).reduce(Integer::min);
		System.out.println("所有交易中,最小的交易額是"+min.get());
		
		//升級版
		Optional<Transaction> min2 =transactions.stream().min(Comparator.comparing(Transaction::getValue));
		System.out.println("所有交易中,最小的交易額是"+min2.get().getValue());
		
	}
}

好了,上週末學的是Lambda表示式,今個星期學的是Stream流,剩下的時間要去繼續把ZooKeeper學完咯,加油!