函数式接口

  函数接口为lambda表达式和方法引用提供目标类型,就是提供支持的接口里面只有且必须只有一个抽象方法,

  如果接口只有一个抽象方法,java默认他为函数式接口

  @FunctionalInterfafce注解限定只能有一个抽象方法

  • 一个函数式接口有且只有一个抽象方法。
  • 默认方法不是抽象方法,因为它们已经实现了。
  • 重写了超类Object类中任意一个public方法的方法并不算接口中的抽象方法。

@FunctionalInterface规定重写了超类Object类中的任意一个public方法的方法并不算入该接口中的抽象方法计数当中,因为该接口的任何实

现都将具有java.lang.Object或其他地方的实现

内置四大核心函数式接口

其他接口

eg:

@FunctionalInterface
public interface Consumer<T>
接受单个输入参数且没有返回值。和其他大部分函数式接口不同,Consumer被期望用于操作副作用
Represents an operation that accepts a single input argument and returns no result. Unlike most other functional interfaces, Consumer is expected to operate via side-effects.
This is a functional interface whose functional method is accept(Object). @FunctionalInterface
public interface Supplier<T> 表示结果的提供者
Represents a supplier of results.
不需要每次调用时返回新的或者不同的结果
There is no requirement that a new or distinct result be returned each time the supplier is invoked.
该函数式接口的方法时get()
This is a functional interface whose functional method is get(). @FunctionalInterface
public interface Function<T,R>
接受一个参数并返回一个结果
Represents a function that accepts one argument and produces a result.
This is a functional interface whose functional method is apply(Object). @FunctionalInterface
public interface Predicate<T>
对一个参数的断言
Represents a predicate (boolean-valued function) of one argument.
This is a functional interface whose functional method is test(Object).
    1 public class FunctionUse {
    2         public static void main(String[] args) {
    3                 //NumberFormatException
    4                 //System.out.println(Integer.valueOf("a"));
    5                 //只能作用域数字型的字符串
    6                 //System.out.println(Integer.valueOf("11"));
    7                 //NumberFormatException
    8                 //System.out.println(Integer.parseInt("a"));
    9                 Consumer<String> consumer =t->{
   10                         System.out.println("消费者型函数式接口,有参数,无返回值");
   11                         System.out.println("参数是"+t);
   12                 };
   13                 consumer.accept("abc");
   14                 Supplier<String> supplier = ()->{
   15                         System.out.println("无参数,有返回值");
   16                         return "a result";
   17                 };
   18                 supplier.get();
   19 
   20                 Function<String , Integer> function = (String input)->{
   21                         System.out.println("有参数,有返回值");
   22                         return input.length();
   23                 };
   24                 System.out.println(function.apply("Abc"));
   25 
   26                 Predicate<String> predicate = t->{
   27                         return true;
   28                 };
   29                 System.out.println(predicate.test("小仙女"));
   30         }

Lambda表达式

只有函数式接口才能使用lambda表达式

允许把函数作为一个方法的参数传递

可以当成匿名函数使用

使代码变得更加简洁紧凑

语法:

(parameters) -> expression
或者
 (parameters) ->{ statements; }
 
可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。JDK8能够根据上下文推断出来
可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
可选的大括号:如果主体只包含了一个语句,就不需要使用大括号。
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,使用大括号(就)需要显示return出来。  单表达式值不需要return
 
对比匿名函数:

方法引用

若lambda方法提中的功能已经提供了方法实现,可以使用方法引用=》可以理解为lambda表达式的另一种形式

形式

*一:对象::实例方法名
*二:类名::静态方法名
*三(特殊):类名::实例方法名 条件是第一个参数为lambda体的方法调用者

注意:
*①(前两种形式)方法引用所引用的方法的参数列表与返回值类型,需要与函数式接口中抽象方法的参数列表和返回值类型保持一致!(最重要,同样适用于构造引用)
*②(特殊形式)若Lambda的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式:ClassName::MethodName

    1 public class MethodReferenceTest {
    2         /**
    3  * @description 对象 :: 实例方法名
    4  */
    5         @Test
    6         public void test1(){
    7                 PrintStream ps = System.out;
    8                 Consumer<String> con = x -> ps.println(x);
    9                 //hello
   10                 con.accept("hello");
   11 
   12                 PrintStream ps1 = System.out;
   13                 Consumer<String> con1 = ps1::println;
   14                 //world
   15                 con1.accept("world");
   16 
   17                 Consumer<String> con3 = System.out::println;
   18                 //hello world
   19                 con3.accept("hello world");
   20         }
   21         @Test
   22         public void test2(){
   23                 Teacher teacher1 = new Teacher("王尼玛",600,"京山小学");
   24                 Supplier<String> supplier1 = () -> teacher1.getName();
   25                 System.out.println(supplier1.get());
   26                 System.out.println("--------------------------");
   27 
   28                 Supplier<Integer> supplier2 = teacher1 :: getAge;
   29                 System.out.println(supplier2.get());
   30                 System.out.println("--------------------------");
   31 
   32                 Supplier<String> supplier3 = new Teacher("王尼玛",600,"京山小学") ::getName;
   33                 System.out.println(supplier3.get());
   34         }
   35         /**
   36  * @description 类名 :: 静态方法名
   37  */
   38         @Test
   39         public void test3(){
   40                 //Integer 的compare()方法是静态方法
   41                 Comparator<Integer> comparator = (x,y) -> Integer.compare(x,y);
   42                 System.out.println(comparator.compare(2,3));
   43 
   44                 Comparator<Integer> comparator1 = Integer::compare;
   45                 System.out.println(comparator1.compare(4,2));
   46         }
   47         /**
   48  * @description 类名 :: 实例方法名
   49  */
   50         @Test
   51         public void test4(){
   52                 //x为lambda体中的调用者
   53                 BiPredicate<String,String> bp = (x,y) -> x.equals(y);
   54                 System.out.println(bp.test("abc","ABC"));
   55                 System.out.println("--------------");
   56 
   57                 BiPredicate<String,String> bp1 = String::equals;
   58                 System.out.println(bp1.test("abc","cba"));
   59                 System.out.println("-----------");
   60                 //参数e为调用者
   61                 Function<Teacher,String> function = e -> e.show();
   62                 System.out.println(function.apply(new Teacher()));
   63                 System.out.println("----------------");
   64 
   65                 Function<Teacher,String> function1 = Teacher::show;
   66                 System.out.println(function1.apply(new Teacher()));
   67 
   68                 //不是静态方法,也没有参数 不能使用 类名:: 方法名 的形式 Non-static method cannot be referenced from a static context
   69               // Supplier<String> supplier1 = Teacher::show;
   70         }
}

构造引用

/**
*形式:
*对象名::new
*@author夜神
*@notice 最重要的一点,和方法引用一样,需要和函数式接口的抽象方法的返回值类型、参数列表一致
*

*数组构造引用
*类型[]::new
*就是对象::方法的形式
*集合构造引用
*类型::new
*
*/

    1 public class ConstructorReference {
    2         @Test
    3         public void test5(){
    4                 Function<Integer, List<String>> function = ArrayList::new;
    5                 List<String> stringList = function.apply(5);
    6         }
    7 
    8         /**
    9  * 数组引用
   10  * @description
   11  * 形式: 类型[] :: new
   12  * new String[size] ->一个参数一个返回值(String[]对象)->Function接口
   13  */
   14         @Test
   15         public void test4() {
   16                 //lambda表达式
   17                 Function<Integer, String[]> function = args -> new String[args];
   18                 String[] str = function.apply(3);
   19                 System.out.println(str.length);
   20 
   21                 //数组引用
   22                 Function<Integer, String[]> function2 = String[] :: new;
   23                 String[] str2 = function2.apply(4);
   24                 System.out.println(str2.length);
   25         }
   26 
   27         /**
   28  * @description 无参构造
   29  * @because Supplier的抽象方法参数列表为空 ->无参数,有返回值 和无参构造一致
   30  */
   31         @Test
   32         public void test() {
   33                 //lambda表达式的写法
   34                 Supplier<Teacher> supplier = () -> new Teacher();
   35                 System.out.println(supplier.get());
   36                 //升级,构造引用
   37                 Supplier<Teacher> supplier1 = Teacher::new;
   38                 System.out.println(supplier1.get());
   39         }
   40 
   41         /**
   42  * 单参构造
   43  *
   44  * @desctiption Function 支持一个参数,一个返回值
   45  */
   46         @Test
   47         public void test2() {
   48                 //lambda表达式
   49                 Function<String, Teacher> function = x -> new Teacher();
   50                 System.out.println(function.apply("王尼玛"));
   51 
   52                 //构造引用
   53                 Function<String, Teacher> function1 = Teacher::new;
   54                 System.out.println(function1.apply("王尼玛"));
   55         }
   56 
   57         /**
   58  * 双参构造
   59  *
   60  * @description BiFunction支持两个参数和一个返回值
   61  */
   62         @Test
   63         public void test3() {
   64                 //lambda表达式
   65                 BiFunction<String, Integer, Teacher> function = (x, y) -> new Teacher(x, y);
   66                 System.out.println(function.apply("狗东西", 600));
   67 
   68                 //构造引用
   69                 BiFunction<String, Integer, Teacher> biFunction = Teacher::new;
   70                 System.out.println(biFunction.apply("王尼玛", 600));
  }
}

Stream流

Classes to support functional-style operations on streams of elements, such as map-reduce transformations on collections.

类,以支持元素流上的函数式操作,例如集合上的映射-还原转换。

Stream 流提供了惰性计算和并行处理的能力,在使用并行计算方式时数据会被自动分解成多段然后并行处理,最后将结果汇总。所以 Stream 操作可以让程序运

行变得更加高效。

是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列

  • Stream自己不会存储元素
  • Strream不会改变源对象,相反,他们会返回一个持有结果的新Stream
  • Stream的操作是延迟执行的,这意味着他们会等到需要结果时才执行

Stream的操作步骤:

创建Stream:一个数据源,获取一个流

中间操作:一个中间操作链,对数据源的数据进行处理

终止操作:执行中间操作链,并产生结果

创建Stream流的方式

集合提供的Stream()方法

Collectin接口提供了Stream()的默认实现

通过Arrays数组工具创建流

Arrays数组工具提供了静态的创建流的方法

通过Stream类提供的方法创建流

of方法创建指定流

     */
public static<T> Stream<T> of(T t) {
return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
} /**
* Returns a sequential ordered stream whose elements are the specified values.
*
* @param <T> the type of stream elements
* @param values the elements of the new stream
* @return the new stream
*/
@SafeVarargs
@SuppressWarnings("varargs") // Creating a stream from an array is safe
public static<T> Stream<T> of(T... values) {
return Arrays.stream(values);
}

iterate和generate无限流

    //迭代
//public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
Stream.iterate(0, t -> t + 2).limit(10).forEach(System.out::println); //生成
Stream.generate(Math::random).limit(10).forEach(System.out::println);

常用中间操作

• map:通过一个 Function 把一个元素类型为 T 的流转换成元素类型为 R 的流。对每一个元素进行转换操作
• flatMap:通过一个 Function 把一个元素类型为 T 的流中的每个元素转换成一个元素类型为 R 的流,再把这些转换之后的流合并。对每一个元素进行转换操作,再平铺
• filter:过滤流中的元素,只保留满足由 Predicate 所指定的条件的元素。
• distinct:使用 hashCode()与equals ()方法来删除流中的重复元素。 去重
• limit:截断流使其最多只包含指定数量的元素。 限制个数
• skip:返回一个新的流,并跳过原始流中的前 N 个元素。
• sorted:对流进行排序。
• peek:返回的流与原始流相同。当原始流中的元素被消费时,会首先调用 peek 方法中指定的 Consumer 实现对元素进行处理。多用于调试,IDEA可能提示将map变为peek,实际不建议这样做
• dropWhile:从原始流起始位置开始删除满足指定 Predicate 的元素,直到遇到第一个不满足 Predicate 的元素。
• takeWhile:从原始流起始位置开始保留满足指定 Predicate 的元素,直到遇到第一个不满足 Predicate 的元素。

map和flatMap

map 返回一个包含每个元素经过函数操作后产生的对象的流
flatMap 将进每个元素过函数操作后产生的新的对象转换成流,将这些流平铺连接成一个流,而且去除null值 (提取数据合并起来放入一个流中) so用flatMap能进行一对多操作

常用终止操作

foreach:遍历执行

reduce:进行递归计算

collect:生成新的数据结构

执行流程

default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}

返回ReferencePipeline.Head实例

ReferencePipeline实际上是一个双向链表的数据结构。而ReferencePipeline对Stream的操作做了实现,每一个中间操作都会返回一个Stream对象,实际上就是ReferencePipeline对象,因此可以得到结论:Stream底层是通过双向链表来实现的。

源阶段返回的是ReferencePipeline.Head对象,而中间操作阶段返回的是ReferencePipeline对象。在流的源阶段和中间阶段仅仅只是返回了ReferencePipeline对象,并没有做其他的方法调用操作,这也是为什么流在执行中间操作并不会有任何的输出或者结果产生。

eg

    1         /**
    2  * 筛选与切片
    3  *         filter——接收 Lambda , 从流中排除某些元素。
    4  *         limit——截断流,使其元素不超过给定数量。
    5  *         skip(n) —— 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
    6  *         distinct——筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素
    7  *      map——映射,接收 Lambda,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
    8  *
    9  */
   10         //filter 过滤
   11         @Test
   12         public void test4(){
   13                 Stream<User> stream = userList.stream()
   14                                 .filter(x -> {
   15                                         System.out.println("中间过滤操作");
   16                                         return x.getId()>12;
   17                                 });
   18                 stream.forEach(System.out::println);
   19         }
   20         //limt 截流
   21         @Test
   22         public void test5(){
   23                 Stream<User> stream = userList.stream()
   24                                 .filter(x -> x.getId()>12)
   25                                 .limit(2);//只要两个,满足后不会再迭代 e g
   26                 stream.forEach(System.out::println);
   27         }
   28         //skip跳过
   29         @Test
   30         public void test6(){
   31                 Stream<User> stream = userList.stream()
   32                                 .filter(x -> x.getId()>12)
   33                                 .skip(1)//把e跳过了
   34                                 .limit(2);//g d
   35                 stream.forEach(System.out::println);
   36         }
   37         //distinct 去重
   38         @Test
   39         public void test7(){
   40                 System.out.println(userList);
   41 
   42                   userList.stream()
   43                                         .distinct()
   44                                         .forEach(System.out::println);
   45         }
   46         /**
   47  * map 映射
   48  * Returns a stream
   49  * consisting of the results
   50  * of applying the given function
   51  * to the elements of this stream.
   52  * 返回一个Stream,包含所有被函数作用后产生的新值。元素个数一一对应。
   53  *接收 Lambda , 将元素转换成其他形式或提取信息。
   54  * 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
   55  *
   56  * flatMap 平面映射
   57  * 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流(平铺)连接成一个流
   58  * 元素个数可能更多,因为把所有流中的值连接成一个流,而一个流中可能有多个值
   59  */
   60         @Test
   61         public void test8(){
   62                 //map 返回一个包含每个元素经过函数操作后产生的对象的流
   63                 Stream<Object> objectStream = userList.stream()
   64                                 .distinct()
   65                                 .map(x -> {
   66                                         if (x.getId() > 11) {
   67                                                 List<Object> list = new ArrayList<>();
   68                                                 list.add(x);
   69                                                 return list;
   70                                         }
   71                                         return null;
   72                                 });//返回的是Stream<R> R:返回值类型
   73                 //[null, [User{id=13, name='e', age=25}], [User{id=15, name='g', age=28}], [User{id=18, name='d', age=30}]]
   74                 System.out.println(objectStream.collect(Collectors.toList()));
   75                 System.out.println("------------------------------");
   76                 //flatMap 将进每个元素过函数操作后产生的新的对象转换成流,将这些流平铺连接成一个流,而且去除null值
   77                 Stream<Object> objStream = userList.stream()
   78                                 .distinct()
   79                                 .flatMap(x -> {
   80                                         if (x.getId()>11){
   81                                                 List<Object> list = new ArrayList<>();
   82                                                 list.add(x);
   83                                                 return list.stream();
   84                                         }
   85                                         return null;
   86                                 });
   87                 

使用流进行自定义去重

单属性去重

List<Student> collect = list.stream().collect(
Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(People::getName))), ArrayList::new));

多属性去重

通常多个属性值之间用“;”隔开

1 ArrayList<Student>  collect1 = list.stream().collect(collectingAndThen(
2 toCollection(() -> new TreeSet<>(
3 Comparator.comparing(element -> element.getName() + ";" + element.getAge()))), ArrayList::new));

使用流进行自定义排序

 List<People> peopleList = getPeopleList();
7 // 正序
8 List<People> sortPeople = peopleList.stream()
9 .sorted(Comparator.comparing(People::getName)).collect(Collectors.toList());
10 // [People(name=张三, age=23), People(name=张三, age=20), People(name=李四, age=20)]
11 System.out.println(sortPeople);
12 // 反序 reversed()
13 List<People> reSortPeople = peopleList.stream()
14 .sorted(Comparator.comparing(People::getName).reversed()).collect(Collectors.toList());
15 // [People(name=李四, age=20), People(name=张三, age=23), People(name=张三, age=20)]
16 System.out.println(reSortPeople);
17 // 组合排序 comparing().thenComparing()
18 List<People> combineSort = peopleList.stream()
19 .sorted(Comparator.comparing(People::getName).thenComparing(People::getAge)).collect(Collectors.toList());
20 // [People(name=张三, age=20), People(name=张三, age=23), People(name=李四, age=20)]
21 System.out.println(combineSort);

使用流转List为Map

Collectors下有toMap方法

    public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}
// mergeFunction:解决相同key的碰撞
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction) {
return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}
    public static <T, K, U, M extends Map<K, U>>
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction,
Supplier<M> mapSupplier) {
BiConsumer<M, T> accumulator
= (map, element) -> map.merge(keyMapper.apply(element),
valueMapper.apply(element), mergeFunction);
return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
}

声明一个集合

//声明一个List集合
List<People> list = new ArrayList<>();
list.add(new People("张三", 22));
list.add(new People("张三", 23));
list.add(new People("李四", 24));
 

List转Map

 Map<String, Integer> map = list.stream().collect(Collectors.toMap(People::getName, People::getAge));

key重复,报错

一般会碰到两个问题,key重复和空指异常 key重复可以选用,空指异常就在转换前保证没有null

key重复问题

选用后面的key  (根据业务需求)

// key重复,选用后者
Map<String, Integer> map = list.stream().collect(Collectors.toMap(People::getName, People::getAge, (key1, key2) ->key2));

空指异常问题

转换前就保证没有null

转换时进行判断处理

        Map<String, Integer> map = list.stream().collect(Collectors.toMap(People::getName, p->p.getAge()==null?0:p.getAge(), (key1, key2) ->key2));

Stream流、lambda表达式、方法引用、构造引用的更多相关文章

  1. 函数式接口 & lambda表达式 & 方法引用

    拉呱: 终于,学习jdk8的新特性了,初体验带给我的感觉真爽,代码精简的不行,可读性也很好,而且,spring5也是把jdk8的融入到血液里,总之一句话吧,说的打趣一点,学的时候自己难受,学完了写出来 ...

  2. 5万字长文:Stream和Lambda表达式最佳实践-附PDF下载

    目录 1. Streams简介 1.1 创建Stream 1.2 Streams多线程 1.3 Stream的基本操作 Matching Filtering Mapping FlatMap Reduc ...

  3. [2014-12-30]如何动态构造Lambda表达式(动态构造Lambda查询条件表达式)

    声明 本文对Lambda表达式的扩展,示例代码来源于网络. 场景描述 web开发查询功能的时候,如果查询条件比较多,就会遇到动态组合查询条件的情况.在手写sql的情况下,我们一般会根据传入的参数,针对 ...

  4. 无情的Java 8 之 Stream和lambda表达式篇

    不好意思,最近刷小视频刷的有点上头 看到这图就不自觉的要来一句:"卧槽,无情" 好了,我要开始正经了 JAVA 8 已经推出有一段时间了, 相比之前, 我们操作集合的方式应该是这样 ...

  5. 初识Stream API + Lambda表达式

    使用新特性简化代码,增强可读性 package com.gg.java8; import java.util.*; import org.junit.Test; public class TestLa ...

  6. 009-jdk1.8版本新特性一-展方法,Lambda表达式,函数式接口、方法引用构造引用

    一.JDK1.8 名称:Spider(蜘蛛) 发布日期:2014-03-18 新特性: 1.1.扩展方法[接口的默认方法] Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 defaul ...

  7. java8之lambda表达式&方法引用(一)

    本文将简单的介绍一下Lambda表达式和方法引用,这也是Java8的重要更新,Lambda表达式和方法引用最主要的功能是为流(专门负责迭代数据的集合)服务. 什么是lambda表达式 可以把lambd ...

  8. java8之stream和lambda表达式

    JAVA 8 已经推出有一段时间了, 相比之前, 我们操作集合的方式应该是这样? 代码:List<String> list = new ArrayList<>(); list. ...

  9. 这么简单,还不会使用java8 stream流的map()方法吗?

    一.前言 在日常的开发工作中经常碰到要处理list中数据的问题,比如从数据库中查出了很多学生,由于一些原因需要在内存中找出这些学生中的所有姓名,或者把名为"王五"的语文成绩暂时修改 ...

  10. 黑马Lambda表达式学习 Stream流 函数式接口 Lambda表达式 方法引用

随机推荐

  1. 前后端分离项目创建项目详细过程项、目需求分析、pip换源、创建虚环境、后端目录调整以及解决问题

    引言,本项目是前后端分离的,前端用Vue2 后端用Django,后台管理部分是通过simpleUI完成的项目,项目名称为路飞,是商城类(知识付费项目).本篇文章主要讨论一个前后端分离的项目第一步怎么做 ...

  2. 比较多普勒超声与临床缓解标准对RA放射学进展的预测效能

    比较多普勒超声与临床缓解标准对RA放射学进展的预测效能 de Miguel, et al. EULAR 2015. Present ID: FRI0586. 原文 译文 FRI0586 DOPPLER ...

  3. 分布式任务调度平台XXL-JOB安装

    安装xxl-job-admin 1.拉取镜像 #拉取镜像 docker pull xuxueli/xxl-job-admin:2.3.0 #新建挂载目录 mkdir /usr/local/xxl-jo ...

  4. NOIP2017 - D2T3 - phalanx

    按照思维难度加大和代码难度减小的顺序,我们来看这道题的不同做法. 若你无畏,我亦无畏 - 平衡树 平衡树简直是天然用来维护这种操作的--合并两个区间,提取一个值.我们可以对每个行的前 \(m-1\) ...

  5. vue2 使用x2js json转换成xml

    安装: 在项目终端运行以下命令 cnpm install x2js --save 引用: // 引入模块 import x2js from 'x2js' 全部代码: <template> ...

  6. 基于ArcGIS的三维路网可视化

    1. 引言 ArcGIS作为GIS的集大成者,对于三维可视化方面也有集成,参考自:3D 折线 (polyline) 要素-ArcMap | 文档 (arcgis.com),可以使用ArcGIS来构造与 ...

  7. ding抓回放

    fiddler 添加代码 var sToInsert = "<script src='https://cdn.jsdelivr.net/gh/Tencent/vConsole@3.8. ...

  8. SpringBoot启动失败问题

    SpringBoot启动失败问题 一.现象 pom.xml没有显示报错,也能查看到各种需要的依赖jar包,但在启动时显示 二.原因 网络不好导致maven导包失败或者导包不完整 三.解决办法 进入项目 ...

  9. 【C学习笔记】day3-1 将数组A中的内容和数组B中的内容进行交换。(数组一样大)

    #include <stdio.h> int main() { int a[5]; for (int i = 0; i < 5; i++) { scanf_s("%d&qu ...

  10. VS2022 17.1.6在windows10下打开winform设计器报timed out while connecting to named pipe错误

    .net 6.0的项目,vs2022 17.1.6在windows10下打开winform设计器报timed out while connecting to named pipe错误,同样的项目在wi ...