Stream聚合函式

Seven發表於2021-09-28

Stream班介紹

幼稚園開學的第一天,各們家長把小朋友送到了園裡,各位小朋友都你看看我,我看看你。有的嚎啕大哭,有的呆若木雞....這裡時候園長安排我拿來小本本記錄入園的小朋友....

記錄小朋友

身為程式設計師的我當然不會拿筆來記錄了。我準備程式碼來記錄下、先寫小孩子的類Child在對映基本資訊

@Getter
@Setter
@NoArgsConstructor
public class Child {

    private int age;         //年齡
    private String firstName; //名
    private String lastName; //姓
    private String fullName; //全名
    
    Child(int age, String lastName, String firstName) {
        this.age = age;
        this.lastName = lastName;
        this.firstName = firstName;
        this.fullName = lastName + firstName;
    }
}

在建立一個班名冊類ClassBook來記錄Stream班的入園所有學生!

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class ClassBook {
    private String name = "Stream班名冊"; //班名冊記錄
    private List<Child> kids = new LinkedList<>();//名冊表
}

由於YQ的原因,我們園小班只收了10個小朋友,現在的小朋友可了不得,光這名兒起的就有文化,我先把這些小朋友記錄下來再說!

public class StreamMathApiTest {
    private ClassBook book;
    @Before
    public void __setUp() {
        List<Child> allChild = new LinkedList<>();
        allChild.add(new Child(3.0F, "蕭", "峰"));
        allChild.add(new Child(3.1F, "任", "我行"));
        allChild.add(new Child(3.2F, "郭", "靖"));
        allChild.add(new Child(3.5F, "洪", "七公"));
        allChild.add(new Child(3.6F, "黃", "藥師"));
        allChild.add(new Child(3.9F, "歐", "陽峰"));
        allChild.add(new Child(3.4F, "任", "飛燕"));
        allChild.add(new Child(3.7F, "楊", "過"));
        allChild.add(new Child(3.3F, "楊", "逍"));
        allChild.add(new Child(3.8F, "石", "破天"));
        this.book = new ClassBook("Stream班名冊", allChild);
    }
}

還是寫程式快啊,不用做Excel表格,一個一個輸入。

計算總學生(Count)

剛把這些小學生記錄完,還沒歇著,園長就讓我們彙報下今天一共入園了多少學生~,等待哈,我先跑個程式碼看一看!

@Test
public void test_count() {
  //count 函式
  long count = this.book.getKids().stream().
    count();

  Assert.assertTrue(count == 10l);
}

這不,能讓電腦動的我決不動腦子。一個就算出個10來。我趕緊向園長彙報!園長跨我算的快!剛準備喝口水、園讓又讓我計算下我們班平均年齡!!!沒辦法,我再寫個程式!

計算平均年齡(mapTo(xxx) + Avgage)

@Test
public void test_avg() {
  double avgAge = this.book.getKids().
    stream().
    mapToDouble(Child::getAge).
    average().orElse(0l);

  Assert.assertEquals("Error calc!", "3.45", Double.toString(avgAge));
}

程式真是個好東西,你看不用一個一個輸入,我寫好程式碼,它自動跑出結果就行!幫我算出了平均數為3.45,這不,園長真的再次跨我能幹!笑著說:順便給我算下我們們班最大的年齡是多少!、我一臉無耐。

計算最大/小值(Max/Min)

@Test
public void test_max() {
  //最大值
  Child maxChild = this.book.getKids().stream().
    max((o1, o2) -> {
      //藉助BigDecimal函式來比較,也可以把Float轉成int來進行比較,方法很多種。
      BigDecimal first = new BigDecimal(String.valueOf(o1.getAge()));
      BigDecimal second = new BigDecimal(String.valueOf(o2.getAge()));
      return first.compareTo(second);
    }).get();

  Assert.assertEquals("歐陽峰", maxChild.getFullName());


  //最小值 返回過來即可
  Child minChild = this.book.getKids().stream().
    max((o1, o2) -> {
      BigDecimal first = new BigDecimal(String.valueOf(o1.getAge()));
      BigDecimal second = new BigDecimal(String.valueOf(o2.getAge()));
      return second.compareTo(first);
    }).get();
  Assert.assertEquals("蕭峰", minChild.getFullName());
}

反正不用我一個一個計算,我就做個順水人情,順便把我們們班最小的朋友也給您找出來!省的你還讓我回來算!這不,最大的是

歐陽峰/3歲9個月,最小是的蕭峰/3歲掛0、心想這下都給你整明白了吧!應該不用算啥了吧!這不剛想完,就讓我回來再算下總年齡!

我...好人做到底,送佛送到西!我就再寫一手!

累加(reduce)

@Test
public void test_reduce() {
  Float totalAge = this.book.getKids().stream().
    map(Child::getAge)
    .reduce(0f, Float::sum);
		
  	//Double::sum/Interge::sum/......
  
  Assert.assertEquals(totalAge.toString(), "34.5");
}

算出來了!這加減乘除平均數最大最小都給你整出來了,這下沒有啥要計算了的吧!

好了、今天的Stream教程到此結束!下次待園長吩咐了才做!

程式碼在GitHub

相關文章