公子奇带你进入Java8流的世界(二)

在上一篇中我们带领大家简单的了解流的概念及使用场景,知道了流的本质操作是将外部迭代转为了内部迭代,由此从程序并发性上得到了很大的优化。在本节我们就来好好的介绍流的常见用法。

一、筛选和切片

对于一串流,我们有时需要取出我们需要的流中某些元素,主要是通过谓词筛选。看代码:

首先定义一个POJO,后续操作都基于此来实例化元素。

 1 package com.hz;
 2
 3 /**
 4  * 民警实体类
 5  */
 6 public class Police {
 7     /**
 8      * 民警警号
 9      */
10     private String policeNo;
11     /**
12      * 民警姓名
13      */
14     private String policeName;
15     /**
16      * 民警年龄
17      */
18     private Integer policeAge;
19     /**
20      * 是否退休
21      */
22     private boolean policeIsRetire;
23
24     public Police(String policeNo, String policeName, Integer policeAge, boolean policeIsRetire) {
25         this.policeNo = policeNo;
26         this.policeName = policeName;
27         this.policeAge = policeAge;
28         this.policeIsRetire = policeIsRetire;
29     }
30
31     public String getPoliceNo() {
32         return policeNo;
33     }
34
35     public void setPoliceNo(String policeNo) {
36         this.policeNo = policeNo;
37     }
38
39     public String getPoliceName() {
40         return policeName;
41     }
42
43     public void setPoliceName(String policeName) {
44         this.policeName = policeName;
45     }
46
47     public Integer getPoliceAge() {
48         return policeAge;
49     }
50
51     public void setPoliceAge(Integer policeAge) {
52         this.policeAge = policeAge;
53     }
54
55     public boolean isPoliceIsRetire() {
56         return policeIsRetire;
57     }
58
59     public void setPoliceIsRetire(boolean policeIsRetire) {
60         this.policeIsRetire = policeIsRetire;
61     }
62
63     @Override
64     public String toString() {
65         return "Police{" +
66                 "policeNo=‘" + policeNo + ‘\‘‘ +
67                 ", policeName=‘" + policeName + ‘\‘‘ +
68                 ", policeAge=" + policeAge +
69                 ", policeIsRetire=‘" + policeIsRetire + ‘\‘‘ +
70                 ‘}‘;
71     }
72
73     @Override
74     public boolean equals(Object o) {
75         if (this == o) return true;
76         if (!(o instanceof Police)) return false;
77
78         Police police = (Police) o;
79
80         if (policeIsRetire != police.policeIsRetire) return false;
81         if (!policeNo.equals(police.policeNo)) return false;
82         if (!policeName.equals(police.policeName)) return false;
83         return policeAge.equals(police.policeAge);
84     }
85
86     @Override
87     public int hashCode() {
88         int result = policeNo.hashCode();
89         result = 31 * result + policeName.hashCode();
90         result = 31 * result + policeAge.hashCode();
91         result = 31 * result + (policeIsRetire ? 1 : 0);
92         return result;
93     }
94 }
 1 package com.hz;
 2
 3 import java.util.Arrays;
 4 import java.util.List;
 5
 6 import static java.util.stream.Collectors.toList;
 7
 8 /**
 9  * 筛选某些元素
10  * 包含:filter / distinct / limit / skip
11  */
12 public class FilterAndLimitStreamDemo {
13     public static void main(String[] args) {
14         List<Police> policeList = Arrays.asList(
15                 new Police("P001", "余警官", 27, false),
16                 new Police("P002", "李警官", 32, false),
17                 new Police("P003", "程警官", 25, false),
18                 new Police("P004", "杨警官", 35, false),
19                 new Police("P005", "张警官", 70, true),
20                 new Police("P006", "王警官", 68, true),
21                 new Police("P007", "赵警官", 77, true),
22                 new Police("P008", "刘警官", 64, true),
23                 new Police("P008", "刘警官", 64, true)
24         );
25
26         //***** 1-使用谓词筛选
27         List<Police> filterPolices = policeList.stream().filter(Police::isPoliceIsRetire).collect(toList());
28         System.out.println("结果1: " + filterPolices);
29
30         System.out.println("---------------- 分割线 ---------------------");
31
32         //***** 2-筛选 大于60岁 并 去除重复的数据(是否重复 根据HashCode和equal决定 两者同时)
33         policeList.stream().filter(p -> p.getPoliceAge() > 60).distinct().forEach(System.out :: println);
34
35         System.out.println("---------------- 分割线 ---------------------");
36
37         //***** 3-截流 截取前三位退休的民警
38         policeList.stream().filter(Police :: isPoliceIsRetire).limit(3).forEach(System.out :: println);
39
40         System.out.println("---------------- 分割线 ---------------------");
41
42         //***** 4-跳过几个元素 获取退休民警 并跳过前两位退休民警
43         policeList.stream().filter(Police :: isPoliceIsRetire).skip(2).forEach(System.out :: println);
44     }
45 }

二、映射

映射即将流中的元素进行处理后返回新的流。

 1 package com.hz;
 2
 3 import java.util.Arrays;
 4 import java.util.List;
 5 import java.util.stream.Stream;
 6
 7 import static java.util.stream.Collectors.toList;
 8
 9 /**
10  * 流中映射
11  */
12 public class StreamMapDemo {
13     public static void main(String[] args) {
14         List<Police> policeList = Arrays.asList(
15                 new Police("P001", "余警官", 27, false),
16                 new Police("P002", "李警官", 32, false),
17                 new Police("P003", "程警官", 25, false),
18                 new Police("P004", "杨警官", 35, false),
19                 new Police("P005", "张警官", 70, true),
20                 new Police("P006", "司马警官", 68, true),
21                 new Police("P007", "赵科", 77, true),
22                 new Police("P008", "刘警官", 64, true),
23                 new Police("P008", "刘警官", 64, true)
24         );
25
26         //***** 1-对流元素中的字段进行处理 获取民警的姓名     和      获取民警姓名长度
27         policeList.stream().map(Police :: getPoliceName).forEach(System.out :: println);
28
29         List<Integer> policesNameLength = policeList.stream().map(Police::getPoliceName).map(String::length).collect(toList());
30         System.out.println("结果: " + policesNameLength);
31
32         System.out.println("------------ 分割线 ----------------");
33
34         //***** 2-流的扁平化 将一组单词 重复的字母去除
35         String[] words = {"gong", "zi", "chuan", "qi"};
36         Stream<String> wordsStream = Arrays.stream(words); //将数组转为流对象
37         Stream<String> wordsStream2 = Arrays.stream(words); //将数组转为流对象
38
39         //此时为 将每个单词为一个数组转为一个流即四个流  流本身没有重复   两个流之间是存在重复的
40         List<Stream<String>> streamsList = wordsStream.map(s -> s.split("")).map(Arrays::stream).distinct().collect(toList());
41         System.out.println(streamsList);
42         //wordsStream为一个流 不可多次使用
43         // java8中有个扁平化的处理 为将流中的值组成一个大的流 flatMap
44         List<String> disWordsList = wordsStream2.map(s -> s.split("")).flatMap(Arrays::stream).distinct().collect(toList());
45         System.out.println("结果:" + disWordsList);
46
47         System.out.println("---------------- 分割线 --------------------");
48
49         //***** 3-一个实例 给定两个数字列表,如何返回所有的数对呢?
50         //          例如,给定列表[1, 2, 3]和列表[3, 4],应该返回[(1, 3), (1, 4), (2, 3), (2, 4), (3, 3), (3, 4)]
51         Integer[] ints1 = {1, 2, 3};
52         Integer[] ints2 = {3, 4};
53
54 //        List<List<int[]>> result = Arrays.stream(ints1).map(i -> {
55 //            List<int[]> tempList = Arrays.stream(ints2).map(j -> {
56 ////                int[] temp = new int[2];
57 ////                temp[0] = i;
58 ////                temp[1] = j;
59 ////                return temp;
60 //                return new int[]{i, j};
61 //            }).collect(toList());
62 //            return tempList;
63 //        }).collect(toList());
64
65         //更简化
66         List<List<int[]>> result = Arrays.stream(ints1).map(i -> Arrays.stream(ints2).map(j -> new int[]{i, j}).collect(toList())).collect(toList());
67
68         result.forEach(l -> l.forEach(is -> System.out.println((is[0] + "," + is[1]))));
69     }
70 }

三、查找和匹配

有时我们需要查看数据集中的某些元素是否匹配一个给定的属性。

 1 package com.hz;
 2
 3 import java.util.*;
 4
 5 /**
 6  * 流中查找和匹配
 7  */
 8 public class FindAndMatchDemo {
 9     public static void main(String[] args) {
10         List<Police> policeList = Arrays.asList(
11                 new Police("P001", "余警官", 27, false),
12                 new Police("P002", "李警官", 32, false),
13                 new Police("P003", "程警官", 25, false),
14                 new Police("P004", "杨警官", 35, false),
15                 new Police("P005", "张警官", 70, true),
16                 new Police("P006", "司马警官", 68, true),
17                 new Police("P007", "赵科", 77, true),
18                 new Police("P008", "刘警官", 64, true),
19                 new Police("P008", "刘警官", 64, true)
20         );
21
22         //***** 1-检查流中元素至少匹配一个  民警列表中至少有一名退休民警
23         System.out.println("--------------- anyMatch分割线 ------------------");
24         if (policeList.stream().anyMatch(Police :: isPoliceIsRetire)) {
25             System.out.println("列表存在退休民警...");
26         } else {
27             System.out.println("当前没有退休民警...");
28         }
29
30         System.out.println("----------- allMatch分割线 ------------");
31
32         //***** 2-检查流中是否匹配所有元素  是否为退休民警列表
33         if (policeList.stream().allMatch(Police :: isPoliceIsRetire)) {
34             System.out.println("该列表为一个退休民警列表...");
35         } else {
36             System.out.println("该列表中存在未退休的民警...");
37         }
38
39         System.out.println("------------- noneMatch分割线 -----------");
40         //与allMatch对应的是noneMatch 即所有都不匹配
41         if (policeList.stream().noneMatch(Police::isPoliceIsRetire)) {
42             System.out.println("该列表都不是退休民警");
43         } else {
44             System.out.println("该列表存在退休民警");
45         }
46
47         System.out.println("--------------- 查找分割线 --------------------");
48
49         //***** 3-查找元素 从民警列表中找出任一元素
50         Optional<Police> anyPolice = policeList.stream().findAny();
51         System.out.println(anyPolice);
52         //在这里Optional这是一个容器类,该容器中只能存储一个对象 其中Optional中实现了一些方法用来操作和判断该容器是否有值
53         //这里我们简单了解下,详细后面我们在好好介绍下该类
54         //***** 案例:找出任意一个退休民警 并打印该民警姓名       ifPresent若有值则执行
55         policeList.stream().filter(Police :: isPoliceIsRetire).findAny().ifPresent(p -> System.out.println(p.getPoliceName()));
56         boolean hasValue = policeList.stream().filter(Police::isPoliceIsRetire).findAny().isPresent(); //是否有值isPresent
57         System.out.println("容器中是否有匹配的值:" + hasValue);
58         // 若容器中有值则返回,否则返回一个默认的值
59         Police police = policeList.stream().filter(Police :: isPoliceIsRetire).findAny().orElse(new Police("","",0, false));
60         System.out.println("返回民警: " + police);
61         //获取匹配的民警 有则返回  没有则异常java.util.NoSuchElementException: No value present
62         Police police1 = policeList.stream().filter(Police::isPoliceIsRetire).findAny().get();
63         System.out.println("获取民警: " + police1);
64
65         System.out.println("---------------");
66         //***** 4-查找流中第一个元素
67         Police police2 = policeList.stream().filter(Police::isPoliceIsRetire).findFirst().get();
68         System.out.println("结果: " + police2);
69     }
70 }

四、归约

有时我们又需要将流中所有的元素结合着来处理,此时就需要归约。

package com.hz;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class ReduceDemo {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(5, 4, 3, 9);

        //***** 1-将一组数值求和
        Integer sum = numbers.stream().reduce(0, (a, b) -> a + b);
        System.out.println("sum: " + sum);
        //若reduce未指定第一个参数,则不知实际返回类型,此时语言本身返回一个Optional容器对象
        Optional<Integer> sumOptional = numbers.stream().reduce((a, b) -> a + b);
        System.out.println("sum-optional: " + sumOptional);
        //变化
        sum = numbers.stream().reduce(0, Integer :: sum);
        System.out.println("sum2: " + sum);

        System.out.println("------------ 分割线 --------------");

        //***** 2-获取一组数的最大和最小值
        Optional<Integer> max = numbers.stream().reduce(Integer::max);
        System.out.println("max: " + max);

        Optional<Integer> min = numbers.stream().reduce(Integer :: min);
        System.out.println("min: " + min);

        System.out.println("---------- 分割线 --------");

        //**** 3-一个案例:使用map和reduce统计民警列表中有多少民警
        List<Police> policeList = Arrays.asList(
                new Police("P001", "余警官", 27, false),
                new Police("P002", "李警官", 32, false),
                new Police("P003", "程警官", 25, false),
                new Police("P004", "杨警官", 35, false),
                new Police("P005", "张警官", 70, true),
                new Police("P006", "司马警官", 68, true),
                new Police("P007", "赵科", 77, true),
                new Police("P008", "刘警官", 64, true)
        );

        Integer policeNum = policeList.stream().map(p -> 1).reduce(0, Integer::sum);
        System.out.println("列表中民警数量: " + policeNum);
    }
}

五、一个实例

下面我们通过一个案例来总结一下流的所有操作。

package com.hz;

import java.util.*;

/**
 * 关于流操作的一个案例
 */
public class StreamDemo {
    public static void main(String[] args) {
        List<Police> polices = Arrays.asList(
                new Police("P001", "Y警官", 27, "浙江", 2019),
                new Police("P002", "L警官", 32, "安徽", 2019),
                new Police("P003", "C警官", 25, "安徽", 2015),
                new Police("P004", "Y警官", 35, "浙江", 2015),
                new Police("P005", "Z警官", 31, "上海", 2018),
                new Police("P006", "W警官", 42, "浙江", 2018),
                new Police("P007", "Z警官", 31, "浙江", 2019),
                new Police("P009", "Z警官", 32, "浙江", 2019),
                new Police("P008", "L警官", 49, "浙江", 2019)
        );

//        (1) 找出2019年入职的民警,并按年龄排序(从低到高)。
        polices.stream().filter(p -> p.getPoliceEntryYear() == 2019).sorted(Comparator.comparing(Police::getPoliceAge)).forEach(System.out::println);

        System.out.println("---------------- 分割线 --------------------------");

//        (2) 民警籍贯都在哪里?
        polices.stream().map(Police::getPoliceNativePlace).distinct().forEach(System.out::println);

        System.out.println("---------------- 分割线 --------------------------");

//        (3) 查找所有来自于浙江的民警,并按姓名排序。
        polices.stream().filter(p -> "浙江".equals(p.getPoliceNativePlace())).sorted(Comparator.comparing(Police::getPoliceName)).forEach(System.out::println);

        System.out.println("---------------- 分割线 --------------------------");

//        (4) 返回所有民警的警号,并按警号顺序排序。
        polices.stream().map(Police::getPoliceNo).sorted().forEach(System.out::println);

        System.out.println("---------------- 分割线 --------------------------");

//        (5) 有没有民警籍贯是在安徽的?
        if (polices.stream().anyMatch(p -> "安徽".equals(p.getPoliceNativePlace()))) {
            System.out.println("存在籍贯为安徽的民警...");
        } else {
            System.out.println("不存在籍贯为安徽的民警...");
        }

        System.out.println("---------------- 分割线 --------------------------");

//        (6) 获取籍贯为浙江的民警的年龄之和
        Integer ageSum = polices.stream().filter(p -> "浙江".equals(p.getPoliceNativePlace())).map(Police::getPoliceAge).reduce(0, Integer::sum);
        //以上方式暗中存在一个装箱操作 其实stream中有个数值流可以省去这个隐藏操作
        ageSum = polices.stream().filter(p -> "浙江".equals(p.getPoliceNativePlace())).mapToInt(Police::getPoliceAge).sum();
        System.out.println("所有浙江民警年龄总和:" + ageSum);

        System.out.println("---------------- 分割线 --------------------------");

//        (7) 所有民警中,年龄最大的是多少?
        Optional<Integer> ageMaxOptional = polices.stream().map(Police::getPoliceAge).reduce(Integer::max);
        // 或使用流的max方法
        ageMaxOptional = polices.stream().max(Comparator.comparing(Police::getPoliceAge)).map(Police::getPoliceAge);
        //同样 该方式也可以转为数值流计算
        OptionalInt maxAgeOp = polices.stream().mapToInt(Police::getPoliceAge).max();
        System.out.println(maxAgeOp.getAsInt());
        if (ageMaxOptional.isPresent()) {
            System.out.println("所有民警最大年龄为: " + ageMaxOptional.get());
        } else {
            System.out.println("没有民警...");
        }

        System.out.println("---------------- 分割线 --------------------------");

//        (8) 找到民警中年龄最小的民警
        Optional<Police> ageMinPoliceOptional = polices.stream().reduce((p1, p2) -> p1.getPoliceAge() < p2.getPoliceAge() ? p1 : p2);
        if (ageMinPoliceOptional.isPresent()) {
            System.out.println("年龄最小的民警: " + ageMinPoliceOptional);
        } else {
            System.out.println("列表中没有民警...");
        }

        //其实还有更加简单的方式,流中有个min方法
        ageMinPoliceOptional = polices.stream().min(Comparator.comparing(Police::getPoliceAge));
        System.out.println(ageMinPoliceOptional);
    }

    static class Police {
        private String policeNo;
        private String policeName;
        private Integer policeAge;
        private Integer policeEntryYear;
        private String policeNativePlace;

        public Police(String policeNo, String policeName, Integer policeAge, String policeNativePlace, Integer policeEntryYear) {
            this.policeNo = policeNo;
            this.policeName = policeName;
            this.policeAge = policeAge;
            this.policeNativePlace = policeNativePlace;
            this.policeEntryYear = policeEntryYear;
        }

        public String getPoliceNo() {
            return policeNo;
        }

        public void setPoliceNo(String policeNo) {
            this.policeNo = policeNo;
        }

        public String getPoliceName() {
            return policeName;
        }

        public void setPoliceName(String policeName) {
            this.policeName = policeName;
        }

        public Integer getPoliceAge() {
            return policeAge;
        }

        public void setPoliceAge(Integer policeAge) {
            this.policeAge = policeAge;
        }

        public String getPoliceNativePlace() {
            return policeNativePlace;
        }

        public void setPoliceNativePlace(String policeNativePlace) {
            this.policeNativePlace = policeNativePlace;
        }

        public Integer getPoliceEntryYear() {
            return policeEntryYear;
        }

        public void setPoliceEntryYear(Integer policeEntryYear) {
            this.policeEntryYear = policeEntryYear;
        }

        @Override
        public String toString() {
            return "Police{" +
                    "policeNo=‘" + policeNo + ‘\‘‘ +
                    ", policeName=‘" + policeName + ‘\‘‘ +
                    ", policeAge=" + policeAge +
                    ", policeEntryYear=‘" + policeEntryYear + ‘\‘‘ +
                    ", policeNativePlace=‘" + policeNativePlace + ‘\‘‘ +
                    ‘}‘;
        }
    }

}

六、数值流及构建流

关于数值流我们在上节实例中已经做了简单说明,在流的创建过程中,有时我们并不知道流的内容,此时需要根据变化来创建流对象。

 1 package com.hz;
 2
 3 import java.io.IOException;
 4 import java.nio.charset.Charset;
 5 import java.nio.file.Files;
 6 import java.nio.file.Paths;
 7 import java.util.ArrayList;
 8 import java.util.Arrays;
 9 import java.util.List;
10 import java.util.stream.Stream;
11
12 /**
13  * 我们之前创建的流都是通过一个List对象或数组
14  * 其他方式也是可以创建流的
15  */
16 public class CreateStreamDemo {
17     public static void main(String[] args) {
18         // 1-List创建流
19         List<String> list = new ArrayList<>();
20         Stream<String> stream = list.stream();
21
22         // 2-数组创建流
23         String[] strings = {"Gong", "Zi", "Qi"};
24         Stream<String> stream1 = Arrays.stream(strings);
25
26         // 3-静态方法创建流
27         Stream<String> stream2 = Stream.of("Gong", "Zi", "Qi");
28         Stream.iterate(0, i -> i + 2).limit(10).forEach(System.out::println);
29         Stream<Object> stream4 = Stream.generate(() -> "GongZiQi");
30         //说明: iterate 和 generate 在生成流是需要注意截取,它们都可以做无限流的生成 如下
31 //        Stream.iterate(0, i -> i + 2).forEach(System.out::println); //生成所有偶数 注意
32 //        Stream.generate(Math::random).forEach(System.out::println); //生成所有随机数 0~1之间 注意
33
34         // 4-文件生成流
35         try {
36             Stream<String> stream3 = Files.lines(Paths.get("data.txt"), Charset.defaultCharset());
37         } catch (IOException e) {
38             e.printStackTrace();
39         }
40     }
41 }

原文地址:https://www.cnblogs.com/chuanqi1415583094/p/12168166.html

时间: 2024-10-08 10:21:56

公子奇带你进入Java8流的世界(二)的相关文章

公子奇带你一步一步了解Java8中Lambda表达式

在上一篇<公子奇带你一步一步了解Java8中行为参数化>中,我们演示到最后将匿名实现简写为 1 (Police police) -> "浙江".equals(police.getPoliceNativePlace()); 这是一个带有箭头的函数,这种写法在Java8中即为Lambda表达式.那么我们就来好好的讲讲Lambda表达式. 一 .什么是Lambda表达式 首先我们需要知道Lambda表达式时JDK8中提出的编码风格,它可以简洁地表示可作为参数传递的匿名函数的

公子奇带你一步一步了解Java8中行为参数化

说明:因为本公子一直从事监狱软件开发,所以本系列博客的引入也以此为背景.问题做了简化,只是为了来讲解技术点. 一.问题提出 今日在好好的撸着代码,超哥(民警)找来了,让把监狱30岁以上的民警找给他. 二.功能实现 这个简单.什么也不用说,代码撸起来.首先定义实体类 package com.hz.pojo; /** * 民警实体类 */ public class Police { /** * 民警警号 */ private String policeNo; /** * 民警姓名 */ privat

有上下界的网络流3-有源汇带上下界最小流SGU176

题目大意:有一个类似于工业加工生产的机器,起点为1终点为n,中间生产环节有货物加工数量限制,输入u v z c, 当c等于1时表示这个加工的环节必须对纽带上的货物全部加工(即上下界都为z),c等于0表示加工上界限制为z,下界为0,求节点1(起点)最少需要投放多少货物才能传送带正常工作. 解题思路:    1.直接 增设超级源点ss和超级汇点tt并连上附加边,对 当前图 求 无源汇带上下界可行流    2.将图的汇点sd连一条容量无限制的边到图的源点st,再求一遍 无源汇带上下界可行流    3.

【HDU 4940】Destroy Transportation system(数据水/无源无汇带上下界可行流)

Description Tom is a commander, his task is destroying his enemy’s transportation system. Let’s represent his enemy’s transportation system as a simple directed graph G with n nodes and m edges. Each node is a city and each directed edge is a directe

有源汇带上下界最小流

LOj 模板 思路我就不多说了吧,和有源汇带上下界最大流一样,只不过这次是初流-残流网络最大流.关键这个模板题写的过程无限T一组,让我很绝望.在网上搜罗了很多代码,发现我有些地方可以优化. (1)跑dinic的时候可以使用当前弧优化 (2)在dinic过程中,如果rest已经等于0了,直接返回.不要不管他,感觉没什么影响,其实有的数据会卡死的(千万在边权更新之后再返回). #include<iostream> #include<cstdio> #include<cstring

Java8初体验(二)Stream语法详解

原文链接:http://ifeve.com/stream/ 1. Stream初体验 我们先来看看Java里面是怎么定义Stream的: A sequence of elements supporting sequential and parallel aggregate operations. 我们来解读一下上面的那句话: Stream是元素的集合,这点让Stream看起来用些类似Iterator: 可以支持顺序和并行的对原Stream进行汇聚的操作: 大家可以把Stream当成一个高级版本的

【转】Java8初体验(二)Stream语法详解

原文链接 http://ifeve.com/stream/ Java8初体验(二)Stream语法详解 感谢同事[天锦]的投稿.投稿请联系 [email protected]上篇文章Java8初体验(一)lambda表达式语法比较详细的介绍了lambda表达式的方方面面,细心的读者会发现那篇文章的例子中有很多Stream的例子.这些Stream的例子可能让你产生疑惑,本文将会详细讲解Stream的使用方法(不会涉及Stream的原理,因为这个系列的文章还是一个快速学习如何使用的). 1. Str

这个夏天,飞到北纬18&deg;去玩海&mdash;&mdash;带着小样儿去三亚(二)

    自由行,顾名思义很自由,想去哪去哪,但是对于我们来说也可能意味着不知道该去哪,事先没有做准备,加上之前的两趟跟团游,该去的景点基本都去了一遍,这趟自由行要去哪儿反而没了目标,温度只有32°,却炎热无比,热带的阳光晒到身上,不一会儿就有点烫,这样的天气,将近十点左右,我们带着一大一下俩娃在酒店周边的旅行社询问可以参与的行程,基本上给我们的答复都是你们来得太晚了,要去景点?可以,明天请早!好吧,谁让我们把自由行履行得如此彻底呢,对于明天是否能早起,我依然不敢肯定,既然这样,不如自由得更彻底,

GDI+入门——带你走进Windows图形的世界

一.GDI+基础 1.GDI+简介 GDI+是微软的新一代二维图形系统,它完全面向对象,要在Windows窗体中显示字体或绘制图形必须要使用GDI+.GDI+提供了多种画笔.画刷.图像等图形对象,此外还包括一些新的绘图功能,比如渐变.除锯齿.纹理等. GDI+包括三部分:二维矢量图形的绘制.图像处理和文字显示.GDI+使用的各种类大都包含在命名空间system::Drawing中. 2.常用的数据结构 在使用GDI+显示文字和绘制图形时,需要用到一些数据结构,例如Size.Point.Recta