本文主要是把jdk8裏面的lambda常用的例子擺一擺,忘記了看一看就知道怎麼使用,方便回憶。
0,使用的循環體字段的代碼,也就是操作對象,數據結構之類的,這裏是簡單的 list 數據。
private final List<BigDecimal> prices = Arrays.asList(
new BigDecimal("10"), new BigDecimal("30"), new BigDecimal("17"),
new BigDecimal("20"), new BigDecimal("15"), new BigDecimal("18"),
new BigDecimal("45"), new BigDecimal("12"));
private final List<String> friends = Arrays.asList("Brian", "Nate", "Neal", "Raju", "Sara", "Scott");
private final List<String> editors = Arrays.asList("Brian", "Jackie", "John", "Mike");
private final List<String> comrades = Arrays.asList("Kate", "Ken", "Nick", "Paula", "Zach");
private final List<Person> people = Arrays.asList(
new Person(20, "John"),
new Person(21, "Sara"),
new Person(21, "Jane"),
new Person(35, "Greg")
);
1,初識,簡單對比lambda和常規操作的不同
/**
* 假設超過20塊的話要打九折
*/
private void test11() {
BigDecimal totalOfDiscountedPrices = BigDecimal.ZERO;
for (BigDecimal price : prices) {
if (price.compareTo(BigDecimal.valueOf(20)) > 0) {
totalOfDiscountedPrices = totalOfDiscountedPrices.add(price.multiply(BigDecimal.valueOf(0.9)));
}
}
System.out.println("Total of discounted prices: " + totalOfDiscountedPrices);
}
private void test12() {
final BigDecimal totalOfDiscountedPrices =
prices.stream()
.filter(price -> price.compareTo(BigDecimal.valueOf(20)) > 0)
.map(price -> price.multiply(BigDecimal.valueOf(0.9)))
.reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println("Total of discounted prices: " + totalOfDiscountedPrices);
}
運行結果:
2,集合的使用
/**
* 集合的使用
*/
@Test
public void test2() {
friends.forEach(new Consumer<String>() {
@Override
public void accept(final String name) {
System.out.println(name);
}
});
friends.forEach((final String name) -> System.out.println(name));
friends.forEach((name) -> System.out.println(name));
friends.forEach(name -> System.out.println(name));
friends.forEach(System.out::println);
}
運行結果:
都是從傳統的寫法上,慢慢的過度到Lambda的寫法。
3,列表的轉化
private void test31() {
final List<String> uppercaseNames = new ArrayList<String>();
for (String name : friends) {
uppercaseNames.add(name.toUpperCase());
}
System.out.println(uppercaseNames);
}
private void test32() {
final List<String> uppercaseNames = new ArrayList<String>();
friends.forEach(name -> uppercaseNames.add(name.toUpperCase()));
System.out.println(uppercaseNames);
}
/**
* Steam的map方法可以用來將輸入序列轉化成一個輸出的序列
* map方法把lambda表達式的運行結果收齊起來,返回一個結果集
*/
private void test33() {
friends.stream()
.map(name -> name.toUpperCase())
.forEach(name -> System.out.print(name + " "));
System.out.println();
}
/**
*
*/
private void test34() {
friends.stream()
.map(name -> name.length())
.forEach(count -> System.out.print(count + " "));
}
/**
*
*/
private void test35() {
friends.stream()
.map(String::length)
.forEach(count -> System.out.print(count + " "));
}
運行結果:
都是從傳統的寫法上,慢慢的過度到Lambda的寫法。
4,在集合中查找元素
private void test41() {
final List<String> startsWith = new ArrayList<String>();
for (String name : friends) {
if (name.startsWith("N")) {
startsWith.add(name);
}
}
System.out.println(startsWith);
}
/**
* filter方法接收一個返回布爾值的lambda表達式。
* 如果表達式結果爲true,運行上下文中的那個元素就會被添加到結果集中;
* 如果不是,就跳過它。最終返回的是一個Steam,它裏面只包含那些表達式返回true的元素。
* 最後我們用一個collect方法把這個集合轉化成一個列表
*/
private void test42() {
final List<String> startsWith =
friends.stream()
.filter(name -> name.startsWith("N"))
.collect(Collectors.toList());
System.out.println(startsWith);
}
運行結果:
5,lambda表達式的重用
/**
* lambda表達式帶來的冗餘
*/
private void test51() {
final long count1 = friends.stream().filter(name -> name.startsWith("N")).count();
final long count2 = editors.stream().filter(name -> name.startsWith("N")).count();
final long count3 = comrades.stream().filter(name -> name.startsWith("N")).count();
System.out.println(count1 + " " + count2 + " " + count3);
}
/**
* 重用
*/
private void test52() {
final Predicate<String> startsWith = name -> name.startsWith("N");
final long count1 = friends.stream().filter(startsWith).count();
final long count2 = editors.stream().filter(startsWith).count();
final long count3 = comrades.stream().filter(startsWith).count();
System.out.println(count1 + " " + count2 + " " + count3);
}
運行結果:
6,閉包 使用詞法作用域和閉包
/**
* 第一個predicate判斷名字是否是以N開頭的,第二個是判斷是否以B開頭的。
* 我們把這兩個實例分別傳遞給兩次filter方法調用。
* 這樣看起來很合理,但是兩個predicate產生了冗餘,它們只是那個檢查的字母不同而已。
*/
private void test61() {
final Predicate<String> startsWith1 = name -> name.startsWith("N");
final Predicate<String> startsWith2 = name -> name.startsWith("B");
final long count1 = friends.stream().filter(startsWith1).count();
final long count2 = friends.stream().filter(startsWith2).count();
System.out.println(count1 + " " + count2);
}
/**
* filter可不是什麼函數都接受的。它只接受只有一個參數的函數,那個參數對應的就是集合中的元素,返回一個boolean值,
* 它希望傳進來的是一個Predicate。
*/
private void test62() {
final long count1 = friends.stream().filter(checkIfStartsWith("N")).count();
final long count2 = friends.stream().filter(checkIfStartsWith("B")).count();
System.out.println(count1 + " " + count2);
}
public static Predicate<String> checkIfStartsWith(final String letter) {
return name -> name.startsWith(letter);
}
運行結果:
7,Optional
/**
* Optional
*/
@Test
public void test7() {
pickName1(friends, "N");
pickName2(friends, "N");
}
public static void pickName1(List<String> names, String startingLetter) {
String foundName = null;
for (String name : names) {
if (name.startsWith(startingLetter)) {
foundName = name;
break;
}
}
System.out.println(String.format("A name starting with %s: %s", startingLetter, foundName));
}
public static void pickName2(List<String> names, String startingLetter) {
final Optional<String> foundName = names.stream()
.filter(name -> name.startsWith(startingLetter))
.findFirst();
System.out.println(String.format("A name starting with %s: %s", startingLetter, foundName.orElse("No name found")));
foundName.ifPresent(System.out::println);
}
運行結果:
8,MapReduce map(映射)和reduce(歸約,化簡)是數學上兩個很基礎的概念
private void test81() {
System.out.println("Total number of characters in all names: " + friends.stream()
.mapToInt(name -> name.length())
.sum());
}
private void test82() {
final Optional<String> aLongName = friends.stream().reduce((name1, name2) -> name1.length() >= name2.length() ? name1 : name2);
aLongName.ifPresent(name -> System.out.println(String.format("A longest name: %s", name)));
}
private void test83() {
final String steveOrLonger = friends.stream().reduce("Steve", (name1, name2) -> name1.length() >= name2.length() ? name1 : name2);
System.out.println(steveOrLonger);
}
private void test84() {
for (String name : friends) {
System.out.print(name + ", ");
}
System.out.println();
for (int i = 0; i < friends.size() - 1; i++) {
System.out.print(friends.get(i) + ", ");
}
if (friends.size() > 0) {
System.out.println(friends.get(friends.size() - 1));
}
System.out.println(String.join(", ", friends));
System.out.println(friends.stream().map(String::toUpperCase).collect(Collectors.joining(", ")));
}
運行結果:
9,字符串及方法引用
/**
* 字符串及方法引用
*/
@Test
public void test9() {
final String str = "w00t";
str.chars().forEach(ch -> System.out.println(ch));
str.chars().forEach(System.out::println);
str.chars()
.mapToObj(ch -> Character.valueOf((char) ch))
.forEach(System.out::println);
str.chars()
.filter(ch -> Character.isDigit(ch))
.forEach(ch -> printChar(ch));
}
private static void printChar(int aChar) {
System.out.println((char) (aChar));
}
10,Comparator
private void testA7(List<Person> people) {
final Function<Person, Integer> byAge = person -> person.getAge();
final Function<Person, String> byTheirName = person -> person.getName();
printPeople("Sorted in ascending order by age and name: ",
people.stream()
.sorted(comparing(byAge).thenComparing(byTheirName))
.collect(Collectors.toList()));
}
private void testA6(List<Person> people) {
final Function<Person, String> byName = person -> person.getName();
List<Person> list = people.stream()
.sorted(comparing(byName))
.collect(Collectors.toList());
printPeople("Sorted in ascending order by name: ", list);
}
private void testA5(List<Person> people) {
List<Person> list = people.stream()
.sorted((person1, person2) ->
person1.getName().compareTo(person2.getName()))
.collect(Collectors.toList());
printPeople("Sorted in ascending order by name: ", list);
}
private void testA4(List<Person> people) {
people.stream()
.max(Person::ageDifference)
.ifPresent(eldest -> System.out.println("Eldest: " + eldest));
}
private void testA3(List<Person> people) {
people.stream()
.min(Person::ageDifference)
.ifPresent(youngest -> System.out.println("Youngest: " + youngest));
}
private void testA2(List<Person> people) {
Comparator<Person> compareAscending = (person1, person2) -> person1.ageDifference(person2);
Comparator<Person> compareDescending = compareAscending.reversed();
List<Person> list = people.stream().sorted(compareAscending).collect(Collectors.toList());
printPeople("Sorted in ascending order by age: ", list);
list = people.stream().sorted(compareDescending).collect(Collectors.toList());
printPeople("Sorted in descending order by age: ", list);
}
private void testA1(List<Person> people) {
List<Person> ascendingAge = people.stream().sorted((person1, person2) -> person1.ageDifference(person2))
.collect(Collectors.toList());
printPeople("Sorted in ascending order by age: ", ascendingAge);
List<Person> descendingAge = people.stream().sorted((person1, person2) -> person2.ageDifference(person1))
.collect(Collectors.toList());
printPeople("Sorted in descending order by age: ", descendingAge);
}
public static void printPeople(final String message, final List<Person> people) {
System.out.println(message);
people.forEach(System.out::println);
}
運行結果:
Sorted in ascending order by age:
Person{age=20, name='John'}
Person{age=21, name='Sara'}
Person{age=21, name='Jane'}
Person{age=35, name='Greg'}
Sorted in descending order by age:
Person{age=35, name='Greg'}
Person{age=21, name='Sara'}
Person{age=21, name='Jane'}
Person{age=20, name='John'}
Sorted in ascending order by age:
Person{age=20, name='John'}
Person{age=21, name='Sara'}
Person{age=21, name='Jane'}
Person{age=35, name='Greg'}
Sorted in descending order by age:
Person{age=35, name='Greg'}
Person{age=21, name='Sara'}
Person{age=21, name='Jane'}
Person{age=20, name='John'}
Youngest: Person{age=20, name='John'}
Eldest: Person{age=35, name='Greg'}
Sorted in ascending order by name:
Person{age=35, name='Greg'}
Person{age=21, name='Jane'}
Person{age=20, name='John'}
Person{age=21, name='Sara'}
Sorted in ascending order by name:
Person{age=35, name='Greg'}
Person{age=21, name='Jane'}
Person{age=20, name='John'}
Person{age=21, name='Sara'}
Sorted in ascending order by age and name:
Person{age=20, name='John'}
Person{age=21, name='Jane'}
Person{age=21, name='Sara'}
Person{age=35, name='Greg'}
11,收集器
/**
* 收集器
*/
@Test
public void testB() {
testB1();
testB2();
testB3();
testB4();
testB5();
testB6();
}
private void testB6() {
Comparator<Person> byAge = Comparator.comparing(Person::getAge);
Map<Character, Optional<Person>> oldestPersonOfEachLetter =
people.stream()
.collect(Collectors.groupingBy(person -> person.getName().charAt(0),
Collectors.reducing(BinaryOperator.maxBy(byAge))));
System.out.println("Oldest person of each letter:");
System.out.println(oldestPersonOfEachLetter);
}
@Test
public void testB5() {
Map<Integer, List<String>> nameOfPeopleByAge =
people.stream()
.collect(
Collectors.groupingBy(Person::getAge, Collectors.mapping(Person::getName, Collectors.toList())));
System.out.println("People grouped by age: " + nameOfPeopleByAge);
}
/**
* to Map<Integer, List<Person>>
*/
@Test
public void testB4() {
Map<Integer, List<Person>> peopleByAge =
people.stream()
.collect(Collectors.groupingBy(Person::getAge));
System.out.println("Grouped by age: " + peopleByAge);
}
/**
* to list
*/
private void testB3() {
List<Person> olderThan20 =
people.stream()
.filter(person -> person.getAge() > 20)
.collect(Collectors.toList());
System.out.println("People older than 20: " + olderThan20);
}
/**
* to list
*/
private void testB2() {
List<Person> olderThan20 =
people.stream()
.filter(person -> person.getAge() > 20)
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
System.out.println("People older than 20: " + olderThan20);
}
/**
* to list
*/
private void testB1() {
List<Person> olderThan20 = new ArrayList<>();
people.stream()
.filter(person -> person.getAge() > 20)
.forEach(person -> olderThan20.add(person));
System.out.println("People older than 20: " + olderThan20);
}
輸出結果: