这个极简的浏览器引擎是参照GitHub上的robinson上写的,基本上就是rust翻译成java,附上我仓库的地址,这个过程中我遇到了几个问题。
递归
在这个简单的浏览器引擎项目里,很多地方都用到了递归的写法。dom树的解析,样式树的解析以及布局树的解析等。刚开始时,我也比较懵,但通过这个例子,可以了解其中的思想。
当函数直接或者间接调⽤⾃⼰时,则发⽣了递归。
计算阶乘的方法就是典型的递归方法:
public static void main(String[] args) {
//5的阶乘是720
System.out.println(f(6));
}
public static int f(int num) {
//递归方法特点二:至少有一个结束条件也就是至少有一个出口
if (num == 1) {
return 1;
}
//递归方法的特点一:在方法中调用自己
return num * f(num - 1);
}
大概就是这样子
递归的过程:
递归三要素:
1.一定有一种可以退出程序的情况
2.总是在尝试将一个问题化简到更小的规模
3.父问题与子问题不能有重叠的部分
stream流的用法
对于stream流可以拆分为3个步骤:
1)创建流:
通过数据源(如:集合、数组)获取流
2)处理流:(中的数据)
对流中的数据进行处理(处理是延迟执行的)
3)收集流:(中的数据)
通过调用收集方法,真正执行处理操作,并产生结果
所有的 Collection 集合都可以通过 stream 默认方法获取流(顺序流),数组没有方法,但数组可以通过Stream 接口的静态方法 of 可以获取数组对应的流。
stream流中常用的方法可以分为两种:
1.延迟方法:返回值类型仍然是 Stream 接口自身类型的方法,支持链式调用。(除了终结方法外,其余方法均为延迟方法。)
2.终结方法:返回值类型不再是 Stream 接口自身类型的方法,因此不再支持类似 StringBuilder 那样的链式调用。
其中用到的延迟方法
1.过滤:filter。用于过滤。通过filter方法设置过滤条件,可以将流中的元素过滤。将一个流转换成另一个子集流。
public static void main(String[] args) {
//创建一个流
Stream<String> stream = Stream.of("张三丰", "刘德华", "张国荣", "彭于晏", "纳什", "吴彦祖", "吴绮蓉");
//对流中元素过滤,只要姓张的人
Stream<String> stream2 = stream.filter(name -> {
return name.startsWith("张");
});
//遍历过滤后的流
stream2.forEach(name -> System.out.println(name));
}
2.映射(转换):map。如果需要将流中的元素映射到另一个流中,可以使用 map 方法。该接口需要一个 Function 函数式接口参数。 java.util.stream.Function 函数式接口,其中唯一的抽象方法为
R apply(T t);
将一种T类型转换成为R类型,而这种转换的动作,就称为“映射"。
public void test(){
//创建一个流,里面是字符串类型的整数
Stream<String> stream1 = Stream.of("2", "32", "2", "33", "2");
//把stream1流中的整数全部转成int类型
Stream<Integer> stream2 = stream1.map((String s) -> {
return Integer.parseInt(s);
});
//遍历
stream2.forEach((i)-> System.out.println(i));
}
3.定制排序:sorted(Comparator com):
public void test2(){
List<Integer> integers = List.of(124, 2, 15, 12, 51, -5, 5);
// 按照自然排序
integers.stream().sorted().forEach(System.out::println);
System.out.println("---------");
List<Integer> integers2 = List.of(124, 2, 15, 12, 51, -5, 5);
// 定制排序(大到小),需要传入Comparator接口(如果流中的是引用类型,只能用定制排序)
integers2.stream().sorted((e1,e2) -> {
return e2-e1;
}).forEach(System.out::println);
}
用到的终结方法:
1.收集 collect(Collector c):将流转化为其他形式,接收一个Collector接口的实现
public void test7(){
List<Person> list = new ArrayList<>();
list.add(new Person("马化腾",25,3000));
list.add(new Person("李彦宏",27,2545));
list.add(new Person("雷军",35,4515));
list.add(new Person("马云",55,9877));
// 把年龄大于30岁的人,转成一个list集合
List<Person> collect = list.stream().filter(person -> person.getAge() > 30).collect(Collectors.toList());
}