java8數值流與物件流的相互轉換
阿新 • • 發佈:2019-01-02
環境java8
準備工作:
數值流:就是基礎資料型別構成的流
數值流跟物件流之間可以相互轉化
1. mapToDouble將 物件流轉換為 數值流
2. 將數值流轉換為物件流
注意:.boxed() 等價於下面
.mapToObj(Double::valueOf||Integer::valueOf||Long::valueOf)
3數值流的相互轉換
eg:double陣列轉為int陣列
4.獲取數值範圍
IntegerStream LongStream的2個方法
range(包左不包右) rangeClosed(包左包右)
如果你要自定義生成規則呢,還可以使用無限流噢 Stream.generate
下面看例子:
//獲取數值範圍
//獲取1-100的偶數流
@Test
public void test5() {
IntStream.rangeClosed(0, 100)
.filter(a->a%2==0)
.forEach(System.out::println);
}
//是否是質數 private static boolean isPrimes(int num) { int res =(int) Math.sqrt((double)num); return IntStream.rangeClosed(2, res) .noneMatch(i->num%i==0); }
//數值流跟物件流之間可以相互轉化 List<Employee> emps = Arrays.asList( new Employee(102, "李四aa", 59, 6666.66, Status.BUSY), new Employee(102, "李四aaa", 60, 6666.66, Status.BUSY), new Employee(101, "張三bb", 18, 9999.99, Status.FREE), new Employee(103, "王五cc", 28, 3333.33, Status.VOCATION), new Employee(104, "趙六dd", 8, 7777.77, Status.BUSY), new Employee(104, "趙六dd", 8, 7777.77, Status.FREE), new Employee(104, null, 25, 7777.77, Status.FREE) ); @Test public void test4() { //推薦 這裡返回的是double double sum = emps.stream() .mapToDouble(Employee::getSalary) .sum(); System.out.println(sum); //這裡返回的並不是double,因為有可能最大值不存在 OptionalDouble opmax = emps.stream() .mapToDouble(Employee::getSalary) .max(); if (opmax.isPresent()) { System.out.println("最大值:"+opmax.getAsDouble()); }else{ System.out.println("沒有最大值"); } //也可以獲取操作物件 DoubleSummaryStatistics summaryStatistics = emps.stream() .mapToDouble(Employee::getSalary) //獲取數值流 .summaryStatistics(); System.out.println(summaryStatistics.getAverage()); //數值流轉化為物件流 long count = emps.stream() .mapToDouble(Employee::getSalary) // .boxed() 等價於下面 .mapToObj(Double::valueOf) .count(); }
//數值流的相互轉換 eg:double陣列轉int陣列的2種方法 其他的暫時沒想到
@Test
public void test4_1() throws Exception {
double nums[]={1,2,3.8};
//方式1:
// int[] array = IntStream.of((int)nums[0],(int)nums[1],(int)nums[2]).toArray();
//方式2 DoubleStream存的是個序列 推薦
int[] array = DoubleStream.of(nums)
//要使用方法轉換,必須轉換為物件流
.boxed()
.mapToInt(a->a.intValue()).toArray();
//或者Arrays.stream 得到的也是DoubleStream流
// Arrays.stream(nums)
// .boxed()
// .mapToInt(a->a.intValue()).toArray();
System.out.println(Arrays.toString(array));
//但是如果你是使用Stream呢,極不合適
//此時存的是一個數組物件,你需要手動遍歷獲取每個元素,再轉換
//涉及的問題是怎麼把Stream<double[]>轉換為Stream<int[]> 有知道的跟我說下,謝謝
Stream<int[]> res = Stream.of(nums)
.map(a->{
int b[]=new int[a.length];
for (int i = 0; i < a.length; i++) {
b[i]=(int)a[i];
}
return b;
});
res.forEach(s->System.out.print(Arrays.toString(s)));
}
小應用:
//獲取 勾股數 比如1-100之間的 eg:3,4,5
@Test
public void test6() {
//方式1 傳統for迴圈
int[] array = IntStream.rangeClosed(0, 100).toArray();
List<int[]> list=new ArrayList<int[]>();
// for (int i = 3; i < array.length; i++) {
// for (int j = i+1; j < array.length; j++) {
// for (int k = j+1; k < array.length; k++) {
// if (i*i+j*j==k*k) {
// list.add(new int[]{i,j,k});
// }
// }
// }
// }
//方式1優化
for (int i = 3; i < array.length; i++) {
for (int j = i+1; j < array.length; j++) {
if (Math.sqrt(i*i+j*j)%1==0) {
list.add(new int[]{i,j,(int)Math.sqrt(i*i+j*j)});
}
}
}
System.out.println("個數:"+list.size());
list.forEach(s->System.out.println(Arrays.toString(s)));
//方式2
Stream<int[]> result = IntStream.rangeClosed(1, 100)
.filter(a1-> a1>=3)
.boxed() //轉換為物件流,因為要存放陣列物件呢,這個IntStream是不支援的
//將流扁平化,因為每個a都是一個流,而最終需要的是陣列流
.flatMap( a->
IntStream.range(a, 100)
.filter(b->Math.sqrt(a*a+b*b)%1==0)
//轉化為物件流 boxed()與mapToObj(xx)等價
.mapToObj(b-> new int[]{a,b,(int)Math.sqrt(a*a+b*b)})
);
result.forEach(s->System.out.println(s[0]+","+s[1]+","+s[2]));
System.out.println("============================================");
//方式2優化,結果是個double[],尷尬了...
Stream<double[]> result2 =IntStream.rangeClosed(1, 100)
.filter(a1-> a1>=3)
.boxed()
.flatMap( a->
IntStream.rangeClosed(a, 100)
.mapToObj(b->new double[]{a,b,Math.sqrt(a*a+b*b)})
//此時獲取的是一個double陣列
.filter(c->c[2]%1==0)
);
// 你是不是想得到int陣列? 個人覺得只能手動遍歷強制轉換額
result2.forEach(s->System.out.println((int)s[0]+","+(int)s[1]+","+(int)s[2]));
}