虽然现在jdk13都快出来了,但是最主流最稳定还是JDK8吧,JDK8也有很多新特性,一般新特性是对以前旧版本的优化或者衍生出的用法,我个人认为这个JDK8的函数式编程很有用,不仅可以优化代码还可以提高效率。通过看了书籍《Java 8函数式编程》自己提取出了对自己目前有用的一些操作,如果读者感觉不能满足你的需求可以看看书,顺便可以看一下《Java 8 Action》里面也有一些介绍。下面我就先上我的案例代码了哦:
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.IntFunction;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~[基本数据类型列表操作]~~~~~~~~~~~~~~~~~~~~~~~~~~");
System.out.println("---------[生成[n,m)的数组]-------------");
int[] intArray1 = IntStream.range(2, 9).toArray();
for (int anInt : intArray1) {
System.out.print(anInt + "\t");
}
System.out.println("\n---------[生成[n,m)的列表(基本数据类型装箱)]-------------");
List integerCollect = IntStream.range(2, 9).boxed().collect(Collectors.toList());
integerCollect.forEach(integer -> System.out.print(integer + "\t"));
// List获取到基本数据类型的流
IntStream intStream = integerCollect.stream().mapToInt(Integer::intValue);
System.out.println("\n---------[生成[n,m)的偶数数组]-------------");
int[] intArray2 = IntStream.range(2, 9).filter(i -> i % 2 == 0).toArray();
for (int i : intArray2) {
System.out.print(i + "\t");
}
System.out.println("\n---------[[n,m)的平均数]-------------");
double asDouble = IntStream.range(2, 9).average().getAsDouble();
System.out.println(asDouble);
System.out.println("---------[[n,m)的平方和]-------------");
int sum = IntStream.range(2, 9).map(x -> x * x).sum();
System.out.println(sum);
System.out.println("---------[[n,m)的最大奇数]-------------");
int reduce = IntStream.range(2, 9).filter(x -> x % 2 != 0).max().getAsInt();
System.out.println(reduce);
System.out.println("---------[[n,m)的水仙花数]-------------");
int[] ints = IntStream.range(1, 10000).filter(i -> isNarcissisticNumber(i)).toArray();
for (int anInt : ints) {
System.out.print(anInt + "\t");
}
System.out.println("\n---------[1到3随机生成两个数乘积的概率]-------------");
// 表示N次,N越大概率越准确
final int N = 100000;
double val = 1.0 / N;
// 因为测试的数量大就是用了并行流,效率高点
Map collect =
IntStream.range(0, N).parallel().mapToObj(nxm()).collect(Collectors.groupingBy(x -> x,
Collectors.summingDouble(x -> val)));
collect.entrySet().forEach(value -> System.out.println(value.toString()));
System.out.println("\n~~~~~~~~~~~~~~~~~~~~~~~~~~[实体列表操作]~~~~~~~~~~~~~~~~~~~~~~~~~~");
List userList = new ArrayList<>();
userList.add(new Person(21, "张三", 1, "深圳"));
userList.add(new Person(12, "张思", 0, "上海"));
userList.add(new Person(32, "李四", 1, "武汉"));
userList.add(new Person(21, "王五", 0, "北京"));
userList.add(new Person(22, "赵器", 0, "武汉"));
System.out.println("---------[按城市分组获取全部信息]-------------");
Map> personCollect = userList.stream().collect(Collectors.groupingBy(Person::getCity));
personCollect.entrySet().forEach(value -> System.out.println(value.toString()));
System.out.println("---------[按城市分组获取个数]-------------");
Map numCollect = userList.stream().collect(Collectors.groupingBy(Person::getCity, Collectors.counting()));
numCollect.entrySet().forEach(value -> System.out.println(value.toString()));
System.out.println("---------[按城市分组获取个人姓名]-------------");
Map> nameCollect = userList.stream().collect(Collectors.groupingBy(Person::getCity, Collectors.mapping(Person::getName,
Collectors.toList())));
nameCollect.entrySet().forEach(value -> System.out.println(value.toString()));
System.out.println("---------[按年龄排序]-------------");
List ageCollect = userList.stream().sorted(Comparator.comparingInt(Person::getAge)).collect(Collectors.toList());
ageCollect.forEach(person -> System.out.println(person.toString()));
System.out.println("---------[按照年龄排序只要年龄数据]-------------");
List personAgecollect = userList.stream().map(Person::getAge).sorted().collect(Collectors.toList());
personAgecollect.forEach(age -> System.out.print(age + "\t"));
System.out.println("\n---------[过滤sex为1的数据]-------------");
List filterSexCollect = userList.stream().filter(person -> person.getSex() != 1).collect(Collectors.toList());
filterSexCollect.forEach(person -> System.out.println(person.toString()));
System.out.println("---------[年龄总和]-------------");
Integer sum1 = userList.stream().map(Person::getAge).mapToInt(Integer::intValue).sum();
Integer sum2 = userList.stream().map(Person::getAge).reduce(0, (x, y) -> x + y);
System.out.println("基本数据类型流求和:"+sum1);
System.out.println("封装数据类型流求和:"+sum2);
}
/**
* 判断是否是水仙花数
*
* @param a
* @return
*/
private static Boolean isNarcissisticNumber(Integer a) {
// 水仙花数位数是3位开始
if (a < 100) {
return false;
}
Integer x = a;
Integer sum = 0;
while (x > 0) {
int m = x % 10;
sum += m * m * m;
x = x / 10;
}
return sum.equals(a);
}
/**
* 获取随机数的乘积
*
* @return
*/
private static IntFunction nxm() {
return i -> {
ThreadLocalRandom random = ThreadLocalRandom.current();
int i1 = random.nextInt(1, 4);
int i2 = random.nextInt(1, 4);
return i1 * i2;
};
}
}
@Setter
@Getter
@ToString
@AllArgsConstructor
class Person {
private Integer age;
private String name;
private Integer sex;
private String city;
}
结果如下:
1、Java8采用的是Stream流,这个流分为了并行流和一般流,并行流是数据量大CPU占用高的情况下可以选择并行流,其实主要看机器的性能了。
2、IntStream,LongStream,DoubleStream这些主要是基本数据流,如果要返回封装数据类型调用.boxed()方法
例如:IntStream.range(2, 9).boxed()
3、List的封装数据类型要获取基本数据流,
例如:list.stream().mapToInt(Integer::intValue);
4、可以把条件抽出来独立成函数,减少代码冗余
5、流求值方法有两种:惰性求值法、及早求值法,
惰性求值一般可以理解为记录流的条件,及早求值可以理解为直接获取结果;
例如:IntStream intStream = IntStream.range(2,9); 这个是惰性求值法应用,根据这个流后面还可以加条件,还没有遍历
List integerCollect = IntStream.range(2, 9).boxed().collect(Collectors.toList());这个是及早值求值法的应用,直接根据流获取到结果了,一般我们都采用这个及早值获取结果
因为传统业务都是传集合等,所以很多数据都是固定的,但是有可能可以使用流在后端调用操作,这样调用方直接可以加条件后才会遍历,调用方要什么信息都可以根据自己要求去获取,并且效率也提高了。那本书里面是这么建议的。
6、使用reduce时候前面那个前置的值一定要弄清楚,不是可能会影响最后的结果;
7.。。。。。。。后面发现继续补充,读者们有什么好滴建议都可以发送在评论哦。
《………………………………………………菜鸟起飞中,请各位走过路过的多多指教……………………………………》