java

1.JDK,JRE,JVM的区别?

jdk:Java Development Kit,java开发工具包(jdk包括jvm,和jre)
    包含jre,java基本类库,java开发工具。(还包含编译javac,解释java,打包jar等工具)
jre:Java Runtime Environmentjava运行环境;
    包含java基本类库和java虚拟机。
jvm:虚拟机,是一种规范,可以用软件或硬件来实现,可以屏蔽不同的系统差异。

java的四种技术体系(其中javaSE为核心)
  javaSE:标准版,JavaEE:企业版,JavaME:微型版,JavaCard:智能卡版

 

2:关键字有两个特征

  1.由小写字母构成

  2.有特殊颜色。

3.命名问题

  类名:使用大驼峰(每个单词的首字母大写)

  方法名跟变量名使用小驼峰(第一个单词的首字母小写,其他的大写)

4.基本数据类型(默认值为0)

  1.整数型

    byte(1个字节),short(2个字节),int(4个字节),long(8个字节)

  2.浮点型

    float(4个字节),double(8个字节)

  3.字符型

    char

  4.布尔型

    boolean

5.引用数据类型(默认值为null)

  字符串,数组,类,接口,lambda

  注意实现:1.字符串不是基本类型,而是引用类型;

       2.浮点型可能只是一个近似值,并非精确的值;

       3.数据范围与字节数不一定相关,例如float数据范围比long更加广泛,但是float是4字节,long是8字节;

         4.浮点数当中默认类型是double,如果一定要使用float类型,需要加上一个后缀F,如果是整数,默认是int类型,如果一定要使用long类型,需要加上一个后缀L,推荐使用大写字母后缀。

6.类型转换的两种方式

  1.自动类型转换(隐式转换):范围从小到大

  2.强制类型转换:

eg:
    int num = (int) 100L;
byte/short/char,这三种类型都可以发生数学运算,例如加法"+";
byte/short/char这三种类型在运算的时候,都会被首先提升为int类型,然后再计算。
布尔类型不能发生数据类型转换,即不能转换为0或者1

 7.数字和字符的对照关系表(编码表)

  1.ASCII码表:American Standard Code for Information Interchange,美国信息交换标准代码;

  2.Unicode码表:万国码,也是数字和符号的对照关系,开头0-127部分和ASCII完全相同,但是从128开始包含更多字符。

  48 - “0”

  65 - "A"

  97 - "a"

8.运算符:进行特定操作的符号,例如”+“

  表达式:用运算符连起来的式子叫做表达式,例如20+5

9.前++与后++的区别?(常量不可以使用,只有变量可以)

  前++:变量立刻+1,然后拿着结果进行使用;

  后++:首先使用变量本来的数值,然后让变量+1

10.复合赋值运算符(常量不可以使用,只有变量可以)

  +=,-=,*=,/=,%=

11:比较运算符的结果一定是布尔值。如果多次判断,不能连着写,eg:1<x<3

12:逻辑运算符

  and:&&

  or: ||

  not : !

13:短路

  and,or具有短路效果,如果根据左边已经可以判断得到最终结果,那么右边的代码将不在执行,从而节省一定的性能。

14:三元运算符

  格式:数据类型  变量名称 = 条件判断 ? 表达式A : 表达式B

  eg:int max = a >b ? a : b;

  三元运算符的结果必须被使用。

15:对于byte,short,char三种类型来说,如果右侧赋值的数值没有超过范围,那么javac编译器将会自动为我们补上一个(byte)(short)(char)

16:args主要用途是从命令行读取输入的参数。

17:数据溢出

  超出最大值,最小值的范围,数据会出现一个循环过程。

18:低字节类型数据与高字节数据运算,其结果自动转变为高字节数据。

 19.格式化快捷键方式

    CTRL+ALT+L

自动赋值:CTRL+ALT+V

20.数组

  1:用于存储多个相同类型数据的存储模型

  int[ ]  arr:定义了一个Int类型的数组,数组名是arr

  2:初始化的两种方式

    动态初始化:int [ ]  arr = new   int[3];

    new为数组申请内存空间;

    3:数组长度,数组中的元素个数

21:数组在初始化时,会为存储空间添加默认值

  整数:0

  浮点数:0.0

  布尔值:false

  字符:空字符

  引用数据类型:null

22.内存分配

  栈内存:存储局部变量,定义在方法中的变量,例如arr,使用完毕,立即消失;

  堆内存:存储new出来的内容,数组在初始化时,会为存储空间添加默认值,每一个new出来的东西都有一个地址值,使用完毕,会在垃圾回收器空闲时被回收。

23.方法重载 

  1.方法重载
    多个方法在同一个类中;
    多个方法具有相同的方法名;
    重载方法的参数不相同(类型不同或者数量不同)
  2.方法重载特点
    重载仅对应方法的定义,与方法的调用无关;
判断是否方法重载,看方法名和参数。
引用类型:传递的是地址值。

数组是引用类型

24.成员变量和局部变量的区别(成员变量又分实例成员变量和静态成员变量(static修饰))

区别 成员变量 局部变量
类中位置不同 类中方法外 方法内或声明上
内存中位置不同 堆内存 栈内存
生命周期不同 随着对象的存在而存在,随着对象的消失而消失 随着方法的调用而存在,随着方法的调用完毕而消失
初始化值不同 有默认的初始值 没有默认的初始值,必须先定义,赋值,才能使用

 

25.private关键字

  是一个权限修饰符

  可以修饰成员(成员变量和成员方法)

  作用是保护成员不被别的类使用,被private修饰的成员只能在本类中才能被访问

  被private修饰的成员变量,如果需要被其他类使用,提供相应的操作

    提供"get变量名"方法,用于获取成员变量的值,方法用public修饰;(变量民首字母大写)

    提供"set变量名(参数)" 方法,用于设置成员变量的值,方法用public修饰。(变量民首字母大写)

26.this(相当于python中的self),this与构造方法一般是互存的。

  1.this修饰的变量用于指代成员变量;

  2.什么时候使用this?

    解决局部变量隐藏成员变量、

  3.this代表所在类的对象引用

    方法被哪个对象调用,this就代表哪个对象。

27.构造方法(类似于__init__初始化方法)(没有返回值

  1.如果没有定义构造方法,系统将给出一个默认的无参数构造方法

  2.如果自定义了带参数构造方法,还要使用无参数构造方法,就必须再写一个无参数构造方法;

  3.无论是否使用,都手工书写无参数构造方法。

  4.构造函数里的变量是局部变量,只能在构造函数内部访问。

28.标准类制作

  成员变量

    使用private修饰

  构造方法

    提供一个无参数构造方法

    提供一个带多个参数的构造方法

  成员方法

    提供每一个成员变量对应的setXxx/getXxx()

    提供一个显示对象信息的show()

  创建对象并为其成员变量赋值的两种方式。

29.字符串的比较

  使用 ==做比较

  基本类型:比较的是数据值是否相同

  引用类型:比较的是地址值是否相同

  字符串是对象,它比较内容是否相同,是通过一个方法来实现的,这个方法叫:equals()。

30.java中比较字符串的内容时严格区分大小写

  charAt(int index)方法返回指定索引处的char值

31.String和StringBuilder的区别

  StringBuilder是一个可变的字符串类,内容是可变的;

  String:内容是不可变得。

32.StringBuilder转String: tostring()

  String转StringBuilder: 通过构造方法。

33.Java有自动类型转换。任何基本数据类型,与String类型进行运算,结果都为String类型,运算符为 +

34.char类型用于存放一个字符,值用单引号'表示 (双引号表示字符串)

35.创建一个Hero对象会用到new关键字,但是给一个基本类型变量赋值却不是用new. 因为基本类型是Java语言里的一种内置的特殊数据类型,并不是某个类的对象。
给基本类型的变量赋值的方式叫做 字面值

36.public static void main(String[] args) {} 的作用

  public是访问修饰符,public,公共的,代表被他修饰的类、方法,变量是公共的其他代码都可以访问

  static是静态修饰符,被他修饰的不需要实例化就可以使用,属于类属性,访问方式:类.属性 /静态方法是可以直接调用其他静态方法的。在项目中只会被加载一次。

  void是返回值类型,void代表没有返回值 ;当void不存在时需要return。        

  String是变量类型,字符串类型 args是数的名字,看见String[]了吧,这说明是一个String类型的数组,

  args是这个数组的名称,至于为什么叫args,因为Java语言就是这样设计的。 这些后面都会会,先记住怎么写的就行了

37.else if 相比if的优势

  可以节约运算资源

38:将数组转换为字符串,查看数组

  Arrays.toString(数组)

39:数组

  赋值数组有两种方法:System.arraycopy+copyOfRange 

  与使用System.arraycopy进行数组复制类似的, Arrays提供了一个copyOfRange方法进行数组复制。
不同的是System.arraycopy,需要事先准备好目标数组,并分配长度。 copyOfRange 只需要源数组就就可以了,通过返回值,就能够得到目标数组了。
除此之外,需要注意的是 copyOfRange 的第3个参数,表示源数组的结束位置,是取不到的。

40:构造方法

  概念:通过一个类创建一个对象,这个过程叫做实例化
      实例化是通过调用构造方法(又叫做构造器)实现的

  特征:方法名和类名一样(包括大小写)
      没有返回类型
      实例化一个对象的时候,必然调用构造方法

41:idea换行的快捷键操作

  Ctrl + Shift + Enter

42:引用与=

  如果一个变量是基本类型
    比如 int hp = 50;
  我们就直接管hp叫变量
  =表示赋值的意思。
  如果一个变量是类类型
  比如 Hero h = new Hero();
  我们就管h叫做引用。
  =不再是赋值的意思
  =表示指向的意思
  比如 Hero h = new Hero();
  这句话的意思是
  引用h,指向一个Hero对象

43:权限修饰符是通用的,可以修饰变量,方法,和类

成员变量有四种修饰符
  private 私有的,只能本类自身可以访问;
  package/friendly/default 不写,只能在本包内可以访问;
  protected 受保护的

  public 公共的,其他包也能访问该类。
  

注: 红色字体,表示不可行

44:适用情况

  1. 属性通常使用private封装起来
  2. 方法一般使用public用于被调用
  3. 会被子类继承的方法,通常使用protected
  4. package用的不多,一般新手会用package,因为还不知道有修饰符这个东西

  再就是作用范围最小原则
  简单说,能用private就用private,不行就放大一级,用package,再不行就用protected,最后用public。 这样就能把数据尽量的封装起来,没有必要露出来的,就不用露出来了

 45:类属性和对象属性

  当一个属性被static修饰的时候,就叫做类属性,又叫做静态属性
  当一个属性被声明成类属性,那么所有的对象,都共享一个值
  与对象属性对比:
  不同对象的 对象属性 的值都可能不一样。
  比如盖伦的hp 和 提莫的hp 是不一样的。
  但是所有对象的类属性的值,都是一样的

  2.访问类属性的两种方法

    1. 对象.类属性

    2. 类.类属性

46:对象属性初始化有三种情况

  1:申明属性的时候初始化;

  2:构造方法中初始化;

  3:初始化块。

  执行顺序:属性申明>初始化块>初始化块

 47:类属性初始化有2种
1. 声明该属性的时候初始化
2. 静态初始化块
  public static int itemCapacity=8; //声明的时候 初始化
     
    static{
        itemCapacity = 6;//静态初始化块 初始化
    }

 48:类属性,实例属性,类方法,实例方法,构造方法的区别

 
分类 类属性 实例属性 构造方法 类方法 实例方法
概念   属性被static修饰,又叫静态属性 非静态属性 在对类进行实例化时首先会调用构造方法 静态方法 实例方法,非静态方法
用途 所用对象共享一个值 需要对象存在   访问类方法,不需要对象的存在,直接就访问 需要对象存在
访问方式

1:类.类属性(不需要对象的存在,通过类直接访问);

2:对象.类属性

对象.实例属性  

1:类.类方法;

2:对象.类方法

对象.实例方法
使用情况

属性值不变

属性值变化  

如果一个方法,没有调用任何对象属性,那么就可以考虑设计为类方法

如果方法里访问了对象属性,那么这个方法,就必须设计为对象方法
 
 49:单例模式
  实现方式:私有化构造方法使得该类无法在外部通过new 进行实例化;
  单例模式三元素:
    1. 构造方法私有化
    2. 静态属性指向实例
    3. public static的 getInstance方法,返回第二步的静态属性
 50:传参的三种方式
  1:对于成员变量直接通多实例对象赋值进行传参;
  2:对于局部变量通过对象.方法传参;
  3:通过构造方法传参,在实例化对象时传参。
注:如果是基本数据类型,在方法内无法更改数值。(因为基本类型是传值)
51:throws与throw这两个关键字接近,不过意义不一样,有如下区别:
  1. throws 出现在方法声明上,而throw通常都出现在方法体内。
  2. throws 表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某个异常对象。
52.三种异常的特点
  
异常分类 可查异常  运行时异常 错误
  CheckedException RuntimeException Error
出现地点 编译时出现 运行时出现 默认设置下,一般java程序启动的时候,最大可以使用16m的内存
特点 可查异常即必须进行处理的异常,要么try catch住,要么往外抛,谁调用,谁处理 即便不进行try catch,也不会有编译错误 系统级别的异常,通常是内存用光了
 
  运行时异常: 都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。 运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
   非运行时异常 (编译异常):Exception  , 是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。
53:Throwable是类,Exception和Error都继承了该类
  所以在捕捉的时候,也可以使用Throwable进行捕捉
  如图: 异常分Error和Exception
  Exception里又分运行时异常和可查异常。
54:for的两种遍历方式
  1.for each:for(int i : d) 就是遍历int型数组d的 每一次访问数组d的时候读取的数据放入int型的i中。
 
  2.for(int i=0; i<d.length();i++)
55.字节流与字符流的区别
  字节流:InputStream字节输入流
    OutputStream字节输出流
    用于以字节的形式读取和写入数据
  字符流
    Reader字符输入流
    Writer字符输出流
    专门用于字符的形式读取和写入数据
56.数据在java中的保存方式有三种
  1.数组,集合。保存位置在内存中,断电之后不可恢复;
  2.文件,保存在磁盘上,查找效率低下;
  3.数据库,持久化保存,查找效率高。
57.不同编码方式的区别如下,数据通过这些编码在内存中都以16进制的形式存放。
  

 58.流的分类(流就是数据)所有的数据存放在计算机中都是以数字的形式存放的。

分类 输入流/输出流 定义 优缺点
字节流 InputStream/OutputStream 以字节的形式读取和写入数据 每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳
字符流 Reader/Writer 以字符的形式读取和写入数据 每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳
缓存流 BufferedReader/PrintWriter 字符流/字节流 每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取
数据流 DataInputStream/DataOutputStream 字节流  
对象流 ObjectInputStream/ObjectOutputStream 字节流  

 

 59.因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中,但是关闭的流对象,是无法继续写出数据,如果我们既想写出数据,又想继续使用流,就有flush方法

60.java中如何使用可变参数?

  public void test (String ... args){

}以数组的形式接收

//public void test(String[] args){

}

 61.java中的包可以理解为文件夹

 62.多态

  定义:一个事物的多种形态;

  提现方式:方法的重载和重写。

  大白话:一个父类中的方法在多个子类的方法可能不一样,调用该方法后显示的结果有不同的表示形式。

63.重载和重写的区别

  作用范围不同:重载是在同一个类中,方法除了参数不同,其他都相同;重写是在继承产生的,子类对父类的方法进行重写。

   子类若想调用父类的方法,需要使用super关键字。

64.抽象类

  特征:用abstract修饰;

  不能创建对象。功能只能由子类实现。

65.final关键字的用处

  最终的意思。修饰的类不能被继承;修饰的方法不能被重写;修饰的变量叫常量且不能在其他地方更改值。

  抽象类不能被final修饰。

66.常量一般全部大写。

67.接口出现的原因

  一个类可以实现多个接口;

  java中的子类只能继承一个父类不能满足需求(一个父类可以有多个子类);

  关键字:interface;

  接口中只能编写常量和抽象方法

  子类不能继承接口,只能实现;实现接口用implements关键字。

  接口可以继承接口;

  接口不能实例化,new,但是可以有子类。

  接口作为参数的目的:实际上接收的是该接口的实现子类;

  接口和抽象类的区别

    (1)接口类中只能包含抽象方法,抽象类中既可以包含抽象方法也可以包含普通方法

    (2)接口中不能定义静态方法,抽象类中可以定义抽象方法

    (3)接口中只能定义静态常量,不能定义普通变量或非静态的常量,抽象类中则可以定义不同的属性,也可以定义静态的属性

    (4)接口中不包含构造方法,抽象类中可以包含(并不是创建对象而是让子类调用)

    (5)一个类最多只能有一个直接父类,包括抽象类,而一个类可以实现多个接口。

68.throws和throw的区别

  都是自定义异常,throws写在方法名后面,throw写在方法体里面

69.object

  object是java所有类的父类,equal方法用于比较两个对象的值是否相等,返回布尔值,==用于判断两个对象是否是同一个对象,返回布尔值。

70.string是不可变的,stringbuffer是可变的;

71.jsp:html中嵌入了java代码;

  asp:html中嵌入了C#;

72.JDBC常用的三个接口

  1.用于连接的connection接口;

  2.用于执行sql语句的statement接口;

  3.用于获取查询结果的resultset接口;

73.连接数据库的两个步骤

  1.加载驱动;

  2.连接;

74.多态

操作符的多态
  + 可以作为算数运算,也可以作为字符串连接(如果+号两侧都是整型,那么+代表 数字相加
如果+号两侧,任意一个是字符串,那么+代表字符串连接


类的多态
父类引用指向子类对象

  要实现类的多态,需要如下条件
  1. 父类(接口)引用指向子类对象
  2. 调用的方法有重写

75.继承

  实例化子类,父类的构造方法一定会被调用,并且是父类构造方法先调用
  子类构造方法会默认调用父类的 无参的构造方法

76.equals()和==的区别

  equals()用来判断两个对象的内容是否相等;,、

  ==不是object方法,用来判断两者地址是否相等,如果是基本数据类型则判断数值是否相等。

77.final

  修饰类时,表示该类不能被继承;

  修饰方法时,表示子类中该方法不能被重写;

  修饰变量时,表示变量只能被赋值一次;

  修饰引用时,表示该引用只有1次指向对象的机会(h  =new Hero();h就是引用

78.抽象类与接口的区别

  区别1:

    子类只能继承一个抽象类,不能继承多个;

    子类可以实现多个接口;

  区别2:

    抽象类可以定义

      public,protected,package,private;

      静态和非静态属性;

      final和非final属性;

    但是接口中声明的属性,只能是

      public;

      静态的;

      final的

      即便没有显式的声明。

79.java中与abstract抽象不能共存的修饰符有三个,private,final,static;

    

  fianl:首先abstract修饰的类,该类中的方法子类继承之后需要重写的,可是final修饰的
    类不能被继承,也就没子类,方法更不能得到重写,相互冲突;不能共存
  private:私有的意思,方法子类是不能被继承到的,那么方法就没有被重写,可是abstract
    是要求方法重写的也相互冲突;不能共存
  static:static能被实例化可直接调用,abstract是不能被实例化的,冲突,不能共存
80.子类访问父类的方式

 

  使用super(),super的作用就是给父类的私有变量赋值;每个子类的构造函数一定有一个super,如果父类的构造函数是无参的子类中的super可以省略,否则不能省略。

 

81.类加载顺序

  先加载类对象(即静态代码块)然后再构建对象。

82.向上造型

  1.子类的对象可以赋值给父类的变量--子类可以转成父类,而父类不能转为子类。

  2.对象本身并没有发生任何变化,所以不是“类型转换”;

  3.运行时如果不合理就会出现类型转换异常:ClassCastException

  4.向上造型时默认的,不需要运算符;

  5.向上造型总是安全的,也就是父=子。

83.强转的前提条件class类型必须相同;

84.java中不存在对象对对象分覆盖和赋值操作,比如,拿一个子类的对象当做父类的对象来使用。

85.函数的绑定是基于多态,多态是基于继承

  java中的绑定默认是动态绑定,即编译时不知道类型,运行时才能确定类型。

  编译:其实就是javac,类的声明周期,检查类的信息(语法等)是否正确的过程。

86.多态的概念

  当一个父类调用子类的方法时,并不能立即确定具体的数据类型。而是在运行的时候自动去确定具体的数据类型的过程。

87.类与接口继承的异同点(单一继承多实现)

  继承:类只能单一继承;

  接口可以多实现(接口可以继承多个接口);

 

88.抽象类不能实例化,抽象类中的抽象方法是约束子类,非抽象方法是分担子类职责。

89.接口出现的原由

  抽象类的抽象方法子类必须实现包括抽象类的父类(单一继承多实现),由此引出接口,即不必实现所有的抽象方法。

  接口也是一个类,是一种特殊抽象类;

    接口中的方法定义默认为public abstract类型,(只能是公开的)

    接口中的成员变量默认为public static final 都是静态常量;

    jdk8之后允许定义默认方法静态方法,(出现默认方法default,子类不必重写覆盖;静态方法类似抽象类中的非抽象方法可以进行职责分担

    接口中没有构造器。

90.子类覆盖接口中的方法一定是public

91.一个接口可以有多个抽象类以及子类就形成了多个实现。

92.使用接口的原由

  规范,约束(一定是一个接口有多个子类的时候它的价值就提现出来,也是多态的最佳体现)

  方便后续的扩展;

  jdk动态代理,在框架大量的存在比如mybatis的mapper,spring中的aop  

93.枚举(枚举存在的意义是什么?)

  枚举也是一个类,只不过它的实例是在自己内部创建,只能在内部new对象而不能在类外部new对象;

  枚举的构造函数不能是public,protected只能是private,默认就是private;

  为什么是private呢?因为jdk把枚举定义成一个单例模式;

  枚举不能继承枚举,也不能继承类,也不能继承抽象类,只能实现接口;

  枚举有面向对象的特征。

94.单例类中如果存在成员变量容易造成线程不安全的问题。

95.单例模式的特征

  在内存空间只有一份。

96.构造器的功能

  对成员变量进行初始化,如果没有传值则成员变量使用默认值。

97.子类继承父类的目的是让父类分担职责;

  子类实现接口的目的是有多套标准。

98.死锁现象产生的原因

  没有释放锁资源。

100.注解:是一种面向对象的注释

注解处理和注释都起到一个标记的作用,但是注释没办法获取(被标记的文本获取注解信息),但是注解可以通过获取类,方法,属性,参数,包名进行获取
一句话:给反射看,用反射来获取。
101:stream流
  应用场景:处理集合数组等可迭代的数据结构;
  优势:对于集合的遍历,排序,聚合操作等的API功能太单一,而stream可以理解为这些API的集合。
  如果stream流一旦调用了终止方法就代表流已经操作完毕,后续的操作就不会执行
  

102.Stream是一个接口,有两种方式来进行创建流对象。
  一是调用 Stream.接口中的of方法。Stream<User> Stream = Stream.of(user1,user2,user3);
  二是调用集合或者数组中的stream方法来获取 Stream.流对象

103.FileOutputStream文件的输入输出流与stream流的区别,

  类型

    文件流是一个实现类,stream流是一个接口。

  操作对象

    文件流操作持久化层数据,stream流操作集合,数组,内存数据。

104.Stream 终止操作

  findFirst& findAny
  两者在stream(串行)的情况下,两者其实都返回的第一个元素;
  如果是parallelStream(并行)情况下findAny就造成随机返回
  可以看到findAny()操作,返回的元素是不确定的,对于同一个列表多次调用findAny()有可能会返回不同的值。使用
  findAny()是为了更高效的性能。如果是数据较少,串行地情况下,一般会返回第一个结果,如果是并行的情况,那就不能确保是第一个。
105.map与flatmap的区别
  map返回对象;
  flatmap返回流。(返回合并等操作)
 

 

posted on 2021-11-21 20:35  看不见的风  阅读(694)  评论(0)    收藏  举报

导航