JavaSE基础知识(个人总结)

2023-11-17

    声明: 1. 本文为我的个人复习总结, 并那种从零基础开始普及知识 内容详细全面, 言辞官方的文章
              2. 由于是个人总结, 所以用最精简的话语来写文章
              3. 若有错误不当之处, 请指出

基础:

杂记:

  • JRE=JVM+常用类库, JDK=JRE+诸多工具(如javac, jstack, jmap, jconsole)
  • 静态(类的)/非静态(对象的,实例的), 成员属性, 局部变量
  • 说法是静态属性不属于任何一个实例所拥有, 但其实应该理解成它对于所有对象而言是公有的, 任何一个对象改变了它, 那可以看到别的对象的此属性也被改变了
  • 静态的东西, 在javac编译后都放在<cinit>中执行初始化操作; 非静态的东西被放到<init>中执行初始化操作
  • 一个类的生命周期中,静态的东西只能加载时被初始化一次,即静态代码块只能第一次执行
  • 静态的属性生命周期很长, 因为在类卸载时, 它们才会跟着被销毁
  • +=后面的部分实质是被括号括起来的, 而且自带强转效果, 强转为前面部分的类型
  • boolean存储占1个字节, 因为它的底层是byte
  • 浮点数的计算, 都不精确, 1-0.1并不等于0.9
  • switch的类型不可以是 float, double, long, 可以是其他基本类型 & String类型 & 枚举类型
  • 代码块执行顺序:父类静态—>子类静态块—>父类代码—>父类构造器—>子类代码块—>子类构造器
  • 接口继承接口, 用的是extends
  • finalize,main,run如果手动调用的话就是普通方法

基本类型和包装类型:

区别:

  • 包装类型可以有null, 而基本类型不可以

  • 包装类型可以用于泛型, 而基本类型不可以

  • 包装类型占用更多内存, 而基本类型占用内存少

包装类型的cache[], 得在你不主动new的时候才能派上用场

Float和Double没有cache[], 因为小数太多没法缓存

值传递和引用传递:

值传递: 传值

引用传递: 传地址

Java里只有值传递, 基本类型作为参数被传递时肯定是值传递(字面量的拷贝);引用类型作为参数被传递时也是值传递,只不过"值"为 堆中的地址值

方法间传参手段:

  1. 不跨类

    • 直接使用方法形参
    • 设置成本类的成员属性
  2. 跨类

    • 直接进行方法传参
    • 设置成第三方类的一个成员属性
    • 如果不跨线程可以考虑ThreadLocal进行存取

JavaBean:

  1. 有无参构造器: 无参构造器最好显示写上, 因为一旦有了其他构造器, javac就不会自动生成它,而子类构造器默认调super( ), 那就找不到相应构造器了

  2. 有Getter/Setter方法: 在json解析或spring装在bean或springmvc或jsp解析时, 并不是直接调用属性, 而是调用其Getter/Setter方法, 如果没有这些可能报错

  3. 属性不能使用基本数据类型;

    因为如int score时,score为0可能实际数据为0,也可能是因为赋的默认值才为0;

    而如果是Integer时,默认值为null, 就可以和实际数据0区分开了

常见的Object方法:

  1. Object clone( ) 浅拷贝

  2. boolean equals(Object)

  3. int hashCode( )

  4. void finalize( )

  5. Class getClass( )

  6. void wait( )

  7. void notify( ) 唤醒等待在该对象的Monitor上的一个线程

  8. void notifyAll( ) 唤醒等待在该对象的Monitor上的全部线程

  9. String toString( )

浅拷贝&深拷贝:

浅拷贝:

​ 对基本数据类型进行值复制,对引用数据类型复制一个引用指向原始引用的对象,

​ 结果是复制的引用和原始引用指向同一个对象(即只拷贝一层)

实现: 目标类先实现实现Cloneable空接口, 调用方再调用目标类的clone方法(继承自Object类)进行浅拷贝

深拷贝:

​ 对基本数据类型进行值复制,对引用数据类型,创建一个新的对象, 并复制其内容,

​ 结果是复制的引用和原始引用指向不同对象(即递归拷贝多层, 直到最后一层为止)

实现: 使用IO对象流(ObjectInputStream, ObjectOutputStream)进行拷贝

final:

  • 修饰变量表示使之为常量, 修饰方法表示此方法不能被重写, 修饰类说明此类不能被继承
  • 若final修饰引用, 那么引用不可变, 但引用指向的对象是可变的

finally:

  • finally里最好要别写return, 如果非写return, 那么当是基本数据类型或是不可变的String类型时, 是不生效的; 当它是引用类型时, 是可以生效的

finalize:

  • 不重写finalize时, GC时会直接调用finalize( )方法来释放内存

  • 重写finalize时, 此类的实例会被包装为Finalizer类的实例, 它们被unfinalized链表串起来;

    当第一次GC时, 只是把它迁移到引用队列里, 并不进行释放内存;

    得等到第二次GC时,才真正调用finalize方法

    如果重写代码里并不是释放内存得逻辑, 比如将这个垃圾对象再赋值给别的引用, 相当于救了这个对象一命使之不再成为垃圾

不要手动调用System.gc( ), GC太伤性能; 另外GC具体什么时候执行 是JVM决定的, 我们决定不了, 只是"建议"一下

循环:

  • foreach循环, 如果是数组则会被javac编译成fori循环; 如果是集合则被编译成迭代器遍历
  • for( xx : 集合/数组), 这个xx实际上是对集合/数组元素的浅拷贝; 即当它是基本数据类型或是不可变的String类型时, 对xx的修改是不影响原数据的; 当是普通的引用类型时, 是可以影响的
  • 循环嵌套时, 在for外循环上方mark: 一个标记, 然后循环里break mark; 跳出指定的外循环, 否则只能跳出一层循环

Comparable VS Comparator:

Comparable 是实体类本身具有可比较性, compareTo方法写在实体类内部

Comparator 是第三方比较器, 单独是一个类, 用compare方法比较两个元素

若想升序排序, 则应该返回a-b<0即负数, 证明a<b; 返回值>0代表a>b; 返回值==0代表a==b

接口:

  • 方法均必须被public abstract修饰, 可以不显示写出来, 但是不能修改它

  • 属性均必须被public final修饰, 可以不显示写出来, 但是不能修改它

  • 接口中不能写构造器, 因为构造器就是用来初始化的, 而它的属性都是常量了得提前赋值, 没必要再要构造器初始化了

  • java8中, 接口里也可以有static方法和default方法, 这种是非抽象的方法; 目的是让你万不得已才这样做, 而不是建议你直接这样做;

    static方法不可被重写, 但可重名

    default方法可被重写, 重写时不可带default关键字

  • 接口是规范

抽象类:

  • 抽象类也有构造方法, 是给子类用的
  • 抽象类可以不写抽象方法, 但抽象方法只能出现在抽象类或接口中
  • 抽象类不能被final修饰, 因为抽象类必须要有子类才有意义
  • 抽象类用了模板方法设计模式, 给子类提供个模板, 剩下的功能由子类自己实现

继承抽象类用extends, 实现接口用implement;

继承只有单继承, 实现有多实现; extends写前面, implement写后面

重写:

想要重写父类方法, 必须遵循3个规则:

  1. 抛出的异常范围≤父类
  2. 返回值≤父类
  3. 方法权限修饰符≥父类

例题: 这个会报错的, 因为"方法权限修饰符≥父类"这个规则, 子类的默认权限<父接口隐藏的public权限

public interface Person{
    void eat( );
}

public class Student extends Person{
    void eat( ){
        System.out.println( );
    }
}

证明有些方法不能被重写:

  1. static方法不能被重写, 可以发现@Override检查后报错, 说明只是同名字

  2. private方法不能被重写, 可以发现@Override检查后报错, 说明只是同名字

  3. final方法不能被重写, 而且不能同名字

重载:

重载方法是编译型多态, 重写方法是运行时多态

方法返回值不作为判断重载的依据, 重载是方法名一样, 但参数不一样(参数个数, 参数类型, 参数顺序)

内部类:

有 静态内部类, 非静态内部类, 匿名内部类, 局部(方法)内部类

  • 非静态内部类里不能使用static关键字

  • 方法内部类使用的外部方法里的变量必须为final常量(可以不显示写出)。[方法内的lambad表达式也一样]

    这是为了改变它的生命周期, 万一这个方法执行完毕后该变量又没有逃逸出去被别人使用, 它就被回收了, 而方法内部类可能依旧需要使用它

    final怎样改变它(外部方法里的变量)的生命周期的?

     final修饰的常量引用在方法区, 指向的对象在堆中; 
    
     方法区的常量引用不会被因此方法调用结束而被回收, 且final常量是可以作为GcRoots对象的, 那么所指的堆中对象就不会被回收, 
    
     从而改变了生命周期
    

    如果要使用user对象, 常用套路:

    • final User finalUser = user, 然后使用finalUser

    如果非要修改user对象, 常用套路:

    • final User[] userArr=new user[]{user}, 然后使用userArr[0]即可; userArr是final的表示此引用不能指向别的对象, 但此对象中的数组元素是可变的
    • 如果同时涉及lambda多线程, 那么就使用原子类, 既保证安全,又保证了final, 原子类引用不能指向别的对象, 但对象内的数据是可变的

动态绑定:

调用方法是动态绑定的(看实例的真正类型是啥, 如果是多态,则按重写调用, 对于同名字的那种视而不见),
而调用属性是静态绑定的(看类的类型是啥)

例题:

  1.  public class Demo01 {
         public static void main(String[] args) {
             A a = new B( );
             // 输出结果是: 20
             System.out.println(a.getResult( ));
         }
     }
     class A {
         private int i = 10;
         public int getResult( ) {
             return i + 10;
         }
     }
     class B extends A {
         private int i = 20;
     }
    
  2.  public class Demo01 {
         public static void main(String[] args) {
             A a = new B( );
             // 输出结果是: 20
             System.out.println(a.getResult( ));
         }
     }
     class A {
         private int i = 10;
         public int getResult( ) {
             return i + 10;
         }
     }
     class B extends A {
         private int i = 20;
         public int getResult( ) {
             return i + 20;
         }
     }
    
  3.  public class Demo01 {
         public static void main(String[] args) {
             A a = new B( );
             // 输出结果是: 20
             // 不是权限不足才被迫调用父类中该方法, 
             // 而是对于那种非重写但同名的方法, 在多态形式调用时,不会理会它,只会理父类中的该方法
             System.out.println(a.getResult( ));
         }
     }
     class A {
         private int i = 10;
         // private权限的getI
         private int getI( ) {
             return i;
         }
         public int getResult( ) {
             return getI( ) + 10;
         }
     }
     class B extends A {
         private int i = 20;
         // private权限的getI, 并非重写, private方法不能被重写, 只是同名字
         public int getI( ) {
             return i;
         }
     }
    
  4.  public class Demo01 {
         public static void main(String[] args) {
             A a = new B( );
             // 输出结果是: 1
             // 对于那种非重写但同名的方法, 在多态形式调用时,不会理会它,只会理父类中的该方法
             System.out.println(a.getI( ));
         }
     }
     
     class A {
         // private权限的getI
         public static int getI( ) {
             return 1;
         }
     }
     
     class B extends A {
         // private权限的getI, 并非重写, private方法不能被重写, 只是同名字
         public static int getI( ) {
             return 2;
         }
     }
    

封装, 继承, 多态

  1. 封装

    即包装, 把客观事物封装成类, 有利于解耦

    权限封装, get/set 可以写一些数据校验逻辑

    参数封装成map, 既美观又拓展性更强, 加参数只需要执行map.put, 而不用修改方法签名

    对功能的封装,封装成一个方法,或对方法进一步封装以加强其功能

    框架的封装

  2. 继承

    避免写重复性的代码, 继承父类后可以拥有父类的一部分东西

    构造器不能被继承

    private可以继承, 但子类无权使用

  3. 多态

    不同的实现类有不同的功能, 有利于功能的拓展

    多态发生的条件: 继承+重写+向上转型

equals相关:

==:

  • 如果==比较的是基本数据类型,那么比较的是两个值是否相等

  • 如果==是比较的两个对象,那么比较的是对象的物理地址是否相等, 即两个对象是否指向了同一块内存

equals:

如果不重写, 则等效于==

很多时候我们想比较的是两个对象的 属性内容是否相等

equals方法要具有以下特性:

  • 自反性。对于任意不为null的引用值x,x.equals(x)一定是true。
  • 对称性。对于任意不为null的引用值x和y,当且仅当x.equals(y)是true时,y.equals(x)也是true。
  • 传递性。对于任意不为null的引用值x、y和z,如果x.equals(y)是true,同时y.equals(z)是true,那么x.equals(z)一定是true。
  • 一致性。对于任意不为null的引用值x和y,如果用于equals比较的对象信息没有被修改的话,多次调用时x.equals(y)要么一致地返回true要么一致地返回false。
  • 对于任意不为null的引用值x,x.equals(null)返回false。

hashcode( ):

hashcode是获取散列哈希码, 默认情况是追求不同对象的哈希码不一样, 有极少情况会两个不同对象的哈希码相等(比如Tom(12岁,猫)可能恰好和Jerry(10岁, 鼠))的哈希值是相等的, 但equals不相等

在HashMap集合中重写equals时, 也需要重写hashcode, 如果只重写了equals方法而不重写hashcode的方法,会造成hashcode的值不同,而equals( )方法判断出来的结果为true。造成相同的对象散列到不同的位置而造成对象的不能覆盖的问题。

hashcode的作用:

  1. 功能上:散列时找到对象所属的坑位, 应该落到哪个数组的位置
  2. 性能上:找到坑位后, 需要对该数组下标位置里已有key进行比较是否相等。直接进行equals代价太大, 因为equals需要比较每个属性, 而hashcode比较起来比较快捷, 可以过滤掉一些一定不相等的key

hashcode相等后,还需要再equals判断:

因为hashcode不相等时那么equals也一定不相等;而hashcode相等时,那equals未必相等

String相关:

String是不可变对象, 底层是private final char value[]; 若要修改, 实质上是返回一个新的对象

String经常被使用, 所以为了复用性, 用字符串常量池进行了池化

不可变&字符串常量池 的好处:

  1. 对象的复用

  2. String的对象不可变, 则hashcode不可变, 可以进行缓存, 不需要重新计算; 所以推荐Map的key为String类型, 寻找值更快

  3. 使多线程安全

    既然是不可变, 那就自然没有多线程安全问题了

  4. 保证其他安全问题

    保护 网络连接地址URL,文件路径path 不被黑客修改

StringBuilder是线程不安全的, StringBuffer是线程安全的

但一般StringBuilder作为局部变量且不暴漏给其他线程, 所以常用些

StringBuilder和StringBuffer都是修改this对象, 实现了链式调用

常量池中的字符串仅是符号,第一次用到时才变为实际的对象

字符串常量池里寸存的是字面量对象

字符串变量拼接的原理是StringBuilder, 即最后toString的时候创建了新字符串对象;

newString(“xxx”)产生了几个对象?

1个或2个

  • 当常量池里已经有了"xxx"时, 就只在堆里创建对象就行了

  • 当常量池里没有"xxx"时, 就现在常量池里创建, 然后再在堆里创建一个

    注意这个不是意为着手动调用.intern就没意义了:

    • 当new String(“xxx”)后, 常量池里一定会有"xxx"了, .intern确实没意义了
    • 但对于字符串拼接 new String(“xxx”)+ new String(“yyy”), 那么"xxxyyy"并不会自动放到常量池, 这时可以手动调用.intern

对于直接字面量相加的字符串, 会被优化为没有拼接这一步

调用 intern( )方法,主动将串池中还没有的字符串对象放入串池(运行时常量池)

  • 1.8 会将这个字符串对象尝试放入串池, 如果有则并不会放入, 如果没有则放入串池, 最终会返回串池中的对象
  • 1.6 会将这个字符串对象尝试放入串池, 如果有则并不会放入, 如果没有会把此对象复制一份放入串池, 最终会返回串池中的对象

所以在s1.intern( ) 没有成功把s1放入串池时, 1.8和1.6做法无差异, 所以s1==s1.intern( );

​ 在s1.intern( ) 成功把s1放入串池时, 1.8和1.6做法有差异(1.8是移动, 1.6是复制), 所以s1!=s1.intern( )

习题:

// jdk1.8时

String s1 = "a"; 
String s2 = "b"; 
String s3 = "a" + "b"; 
String s4 = s1 + s2; 
String s5 = "ab"; 
String s6 = s4.intern( ); 

System.out.println(s3 == s4); 	// false
System.out.println(s3 == s5); 	// true
System.out.println(s3 == s6); 	// true

String x1 = "cd"; 
String x2 = new String("c") + new String("d"); 
String x3=x2.intern( ); 
System.out.println(x1 == x2);	// false
System.out.println(x2 == x3);	// false


String y2 = new String("e") + new String("f"); 
String y3=y2.intern( ); 
String y1 = "ef"; 
System.out.println(y1 == y2);	// true
System.out.println(y2 == y3);	// true
// jdk1.6时

String s1 = "a"; 
String s2 = "b"; 
String s3 = "a" + "b"; 
String s4 = s1 + s2; 
String s5 = "ab"; 
String s6 = s4.intern( ); 

System.out.println(s3 == s4); 	// false
System.out.println(s3 == s5); 	// true
System.out.println(s3 == s6); 	// true

String x1 = "cd"; 
String x2 = new String("c") + new String("d"); 
String x3=x2.intern( ); 
System.out.println(x1 == x2);	// false
System.out.println(x2 == x3);	// false


String y2 = new String("e") + new String("f"); 
String y3=y2.intern( ); 
String y1 = "ef"; 
System.out.println(y1 == y2);	// false
System.out.println(y2 == y3);	// false

String长度的最大值:

  • 在编译期: .class文件的Constant_Utf8_info表 用一个无符号短整型变量记录字符串占用字节大小,

    ​ 所以最大字节为2^16-1=65535, 而最大长度是2^16-2=65534

  • 在运行期: 字符串长度最大值就变成了数组长度的最大值, 数组的对象头里有4个字节记录数组长度, 故最大长度为2^31-1

异常 & 错误

都是Throwable的子类

错误是虚拟机自身造成的, 是程序自身不可以处理的, 比如StackOverFlowError, OutOfMemoryError

异常是程序逻辑不对造成的, 是程序自身可以处理的

  • 异常=编译时异常(大部分是IOException)+运行时异常

  • 见过的异常:

    1. ConcurrentModificationException 并发修改异常,

      比如遍历ArrayList集合期间删除了元素 导致modCount != expectedModCount

      这里的并发并非是线程并发, 而是指一边遍历一遍修改

    2. IllegalAccessException 非法访问权限异常

      如调用别类中的private方法

    3. InstantiationException 实例化异常

      Class的newInstance( )方法创建某个类的实例, 而该类却没有相应构造器

    4. ClassCastException 类型转换异常

    5. NumberFormatException 数据格式异常

try with source 即省略了finally, 把待释放的资源放在try后的( )里, 这里的变量实质上是final的(可以不显示写出来)

try catch finally中, catch 不是必要的

日期类:

SimpleDateFormat是非线程安全的, 因为它内部的calendar属性被暴漏出来, 临界区发生了竞态条件

应该使用JDK8新出来的LocalDateTime类

枚举:

应用场景:

  1. 星期: Monday, Tuesday…
  2. 性别: Man、Woman
  3. 季节: Spring、Summer、Autumn、Winter

枚举的本质是有一个final static 的引用属性, 指向了自己的对象

什么时候用枚举?

  1. 类的对象是确定的有限个数
  2. 当需要定义一组常量时
  3. 如果枚举类中只有一个对象,则可以实现单例模式

特点:

  1. 不能被继承
  2. 不能在外部被new 创建对象
  3. 多个枚举成员用,隔开, 后面什么都没有时, 可以省略;结束符

枚举类的常用方法:

返回值 方法 描述
String name( ) 获取枚举成员的名称
static T valueOf(Class enumType, String name) 获取指定枚举成员名称和类型的枚举成员
String[] values( ) 获取枚举成员的所有值
int compareTo(E o) 比较此枚举与指定对象的 顺序
int ordinal( ) 获取枚举成员的序数(从0开始)
Class<E> getDeclaringClass( ) 获取枚举成员的类对象

泛型:

泛型就是将类型参数化

泛型的优点:

  1. 编译时检查类型是否合法
  2. 省去了强制类型转换的麻烦
  3. 使代码可读性更高

泛型在运行期会被擦除, 都变成Object类型, 这些方法调用时会有checkcast指令去强制类型转换

泛型方法:

泛型 T 是方法独有的, 与所在类上定义的泛型无关

public <T> void fun(T t){

}

静态方法 不可以访问 类上定义的泛型(因为得new 才能传泛型, 而static类初始化阶段 还没有new对象初始化发生),

但可以使用 泛型方法上定义的泛型

通配符 ? 类型:

  1. List<? extends T> 泛型上限是T

  2. List <? super T> 泛型下限是T

  3. List <?> 不确定类型, 可以持有任意类型

错误使用:

  1. ArrayList<Object> list=new ArrayList<Integer>( );
  2. List<Object> list=new ArrayList<Integer>( );

而List<Object> list = new ArrayList<Object>( ); 是正确的, <>里面的类型前后必须得一致才行

IO流:

流的种类:

节点流有: 字节流(读写任何数据格式), 字符流(读写文本格式)

包装流(处理流)有: 缓冲流, 转换流, 数据流, 对象流

形式有: 字节数组形式/文件形式

包装流的反复包装, 使用了装饰者设计模式

转换流(字节转字符):

InputStreamReader 字节输入流 转 字符输入流

OutputStreamWrite 字节输出流 转 字符输出流

序列化:

序列化是把内存中的数据转换成字节流等形式, 使数据能落盘存储网络传输,

分布式节点中要传输数据, 数据得先序列化才能传输

序列化可以打破单例, 所以需要处理一下:

// 待序列化的类写上此方法, 反序列化时依旧保持单实例
protected Object readResolve( ) {
     return instance;
}

Serializable:

  • 需要继承Serializable空接口, 最好要加上public static final long serialVersionUID属性(相当于版本号)

  • 如果没有这个属性, 那么一旦类被修改了, 反序列化时就会报错(相当于每次反序列化会生成新的版本号)

    serialVersionUID 用来表明类的不同版本间的兼容性, 值是多少无所谓, 只要不变就行

  • transient修饰的属性 和 静态属性 是不会被序列化的

serialVersionUID也被static修饰, 为什么serialVersionUID会被序列化?

其实原先的serialVersionUID属性并没有被序列化, JVM在序列化对象时会自动生成一个serialVersionUID; 然后将原先的serialVersionUID属性值 赋值 给自动生成的serialVersionUID

Externalizable:

是Serializable的子接口

重写writeExternal 和 readExternal两个方法, 自己指明要序列化哪些属性

   public void writeExternal(ObjectOutput out) throws IOException {       out.writeObject(name);   }   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {       name = (String) in.readObject( );   }

注解:

是一种可以被程序读取的标记, 可以用来作配置

用@Interface来声明, 属性长得像方法, 使用时, 只有一个value属性的话, value可以省略

注解的传递: 注解A修饰了注解B, 那么注解B去修饰注解C时, 注解C也会被A修饰

元注解:

  1. @Target 声明注解的使用范围

    public enum ElementType {    TYPE, // 类、接口、枚举类    FIELD, // 成员变量(包括:枚举常量)    METHOD, // 成员方法    PARAMETER, // 方法参数    CONSTRUCTOR, // 构造方法    LOCAL_VARIABLE, // 局部变量    ANNOTATION_TYPE, // 注解类    PACKAGE, // 可用于修饰:包    TYPE_PARAMETER, // 类型参数,JDK 1.8 新增    TYPE_USE // 使用类型的任何地方,JDK 1.8 新增}
    
  2. @Retention 声明注解可以活到什么时候

    public enum RetentionPolicy {    SOURCE,    // 源文件保留    CLASS,       // 编译期保留,默认值    RUNTIME   // 运行期保留,可通过反射去获取注解信息}
    
  3. @Inherited 表明 被注解修饰的父类,其子类会自动继承该注解

  4. @Documnent 表明注解可以被javadoc提取生成说明文档

JDK8中注解的新特性:

  1. 新增可用于类型的注解

    ElementType.TYPE_PARAMETER

    ElementType.TYPE_USE

  2. 可重复的注解

    相当于在原先注解上加个重复注解 表示数组容器, 原先注解被多次使用时 就会被放到此数组中

    示例:

    image-20211108124256351

反射:

  • 对于任意一个类, 能获得到它相关的类信息(属性, 方法, 被修饰的注解)
  • 对于任意一个对象,都能够调用它的任意一个属性和方法
  • 以前是对象调方法, 反射是方法调对象, 但这个方法比较特殊, 是java.lang.Method类

反射可以用来突破权限, 但不建议直接这样, 除非你万不得已

函数式编程:

lambad表达式, 即函数也进行匿名, 把函数看作对象; 当接口里只有一个方法时, 可以这样做

方法引用(类调用 反而要比对象调用 支持的更多些), 传入getter方法时常常这样做, 比如Student::getScore

函数式接口:

被@FunctionInterface修饰

  1. Function——函数型接口**(有输入、有返回)**

  2. Predicate——断定型接口**(有输入,返回boolean)**

  3. Consumer——消费型接口**(有输入,无返回)**

  4. Supplier——供给型接口**(无输入,有返回值)**

BiConsumer是有两个参数输入

StreamAPI:

StreamAPI是将集合变为Stream流, 对于Stream流的操作并不会影响原集合, 有丰富的API

如map, flatMap, filter, reduce, sorted

最后通过 .collect(Collectors.toXXX( )) 转为集合

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaSE基础知识(个人总结) 的相关文章

  • Java接口详解

    一 static静态关键字 定义变量不加static关键字 每个对象单独保存一个变量 定义变量加static关键字 静态变量 类变量 共享变量 public static 数据类型 变量名 所有对象会共享该变量 如果一个变量 静态变量 类变
  • java热部署

    Class forName和ClassLoader loadClass 简书 Eclipse安装热部署热加载插件JRebel 免费版 idea也可用 that summer CSDN博客 Eclipse中使用JRebel实现项目热部署 Ma
  • static静态代码块

    static静态代码块 public class Person 静态代码块 在类加载时候执行静态代码块 只会执行一次 static System out println Person static initializer 实例初始化块 每次
  • JavaSE——StringBuffer与StringBuilder拼接字符串详细解释

    目录 一 基本了解 1 1使用字符串频繁拼接会出现什么问题 1 2 了解StringBuffer 1 3 了解StringBuilder 1 4 StringBuffer与StringBuilder的区别 二 StringBuffer的使用
  • Java异常(超详细!)

    1 什么是异常 java提供异常处理机制有什么用 什么是异常 程序执行过程中的不正常情况 异常的作用 增强程序的 健壮性 eg public class ExceptionTest01 public static void main Str
  • Java中的抽象类和接口

    目录 一 什么是抽象类 抽象类在实现多态中的意义 二 接口是什么 通过接口实现多态 三 抽象类和接口的区别 各位铁汁们大家好呀 今天让我们继续学习java 看看java中的抽象类和接口到底是什么 一 什么是抽象类 我们之前学过什么是类 那么
  • jquery循环语句if-else if-else

    jquery循环语句if else if else callbackFun 函数 开始是写的if if else 结果是不管第一个if有没有匹配到 会再次判断 如果匹配到第二个if 则第二个if中的语句执行 没有匹配到第二个if 则else
  • Java中的String的一些常用方法

    家人们好 目录 字符 字节与字符串 字符与字符串 获取指定位置的字符 字符串与字符数组的转换 给定字符串一个字符串 判断其是否全部由数字所组成 字节与字符串 实现字符串与字节数组的转换处理 字符串常见操作 字符串比较 不区分大小写比较 观察
  • Java-进制转换

    常用的进制转换 十进制转二进制 二进制转十进制 十进制转八进制 八进制转十进制 十进制转十六进制 十六进制转十进制 如果二 八 十六之间想转换可以通过十进制做中间者 import java util Scanner import java
  • Java的Properties属性集、获取项目路径的3种方式(干货满满)

    属性集介绍 集合家族中有个成员java util Properties 它继承于Hashtable Properties是使用键值结构存储数据的 但它最大的特点是具有持久化功能 持久化 内存 gt 硬盘 持久化的过程必须依赖于IO流 对IO
  • 多态(polymorphic)

    目录 1 多态的基本介绍 2 多态实现条件 3 重写 重写的介绍 重写和重载的区别 动 静态绑定机制 5 向上转型和向下转型 向上转型 向上转型的特点 总结 向下转型 多态的优缺点 多态是Java三大基本特征中最抽象也是最重要的特征 多态是
  • Scanner中nextInt()和nextLine()详解(秒懂)

    直接上代码 输出结果 结果分析 nextInt 和nextLine 顺序互换代码如下 输出结果 结果分析 解决方法 可以将nextLine 用next 替换 两者nextLine 执行之前再加一个空nextLine 让这个空的清楚掉回车符再
  • XML语言

    XML XML是可扩展的标记语言 标记语言 通过标签来描述数据的一门语言 标签有时我们也将其称之为元素 可扩展 标签的名字是可以自定义的 XML文件是由很多标签组成的 而标签名是可以自定义的 xml学习网站https www w3schoo
  • 8421码

    8421码是中国大陆的叫法 8421码是BCD代码中最常用的一种 在这种编码方式中每一位二值代码的1都是代表一个固定数值 把每一位的1代表的十进制数加起来 得到的结果就是它所代表的十进制数码 二进制 1 1 1 1 十进制 8 4 2 1
  • Java多态

    关于引用的进一步理解 交换值 因为Java方法在传递参数的时候都是值传递 那么如何通过方法实现2个数的值交换 明确 在传引用的时候 到底拿引用干了个啥 class Value public int a public class Test p
  • Java面向对象——图书管理系统(小白也能看的懂!)

    文章目录 一 功能介绍 二 JAVA面向对象思想 包的分装 1 book包 2 user包 较复杂 3 operation包 接口包 三 代码框架的搭建 1 book包 Book类 2 book包 BookList类 3 operation
  • StringUtils常用方法+StringUtils详细介绍

    StringUtils用法 StringUtils详细介绍 博文来源 http yijianfengvip blog 163 com blog static 175273432201212221935832 public static vo
  • java Socket 简单实现客户端与服务器间通信(仿聊天室)

    java Socket TCP协议简单实现客户端与服务器间的通信 打赏 执行效果 启动服务器和3个客户端 进行群聊和私聊 执行过程 服务端 首先创建服务器套接字ServerSocket对象并绑定端口 启动服务器 然后ServerSocket
  • Object&Objects

    Object 概念 Object 是类层次结构的根 每个类都可以将 Object 作为超类 所有类都直接或者间接的继承自该类 换句话说 该类所具备的方法 所有类都会有一份 toString 作用 以良好的格式 更方便的展示对象中的属性值 重
  • Scanner类用法(学习笔记)

    Scanner类用法 学习笔记 后续会补充 1 next 用法 package com yushifu scanner import java util Scanner util java工具包 Scanner类 获取用户的输入 Scann

随机推荐

  • 【CTF/MISC】图片隐写题(binwalk/foremost/010editer配合使用)

    图片隐写 题目 解题思路 binwalk工具查看是否有隐藏文件 foremost工具分离文件 010editer查看二进制数据 寻找解压密码 解题心得 题目连接 题目 题目是一张图片 寻找题目中隐藏的flag 解题思路 一般来说我碰到图片隐
  • SSM框架下实现简单增删查改的具体细节(代码)

    UserInfo public class UserInfo private int id private String username private String password public int getId return id
  • 电子检测报告如何盖骑缝章?

    检测评估报告通常有多页 几十页的报告也不少见 文件中除了要在检测机构盖公章处盖章 还需要盖骑缝章 为了防范风险 防止报告内容被更换的情况 就需要骑缝章的加盖来保证检测报告的整体性 下面以微签为例 展示一下电子检测报告如何盖骑缝章 微签在检测
  • Java线程池面试题整理总结【实习打卡01】

    ThreadLocal GC 之后 key 是否为 null 不一定 1 当使用new ThreadLocal lt gt set s 定义threadlocal时 没有在栈中声明一个变量指向他 那他就是只被弱引用 在gc后 那这个thre
  • 获取微信小程序码实例,建议拿到字节流后可以base64编码再上传图片,得到图片地址进行使用

    接口调用凭证 access token public static String postToken String appId String appKey throws Exception String requestUrl https a
  • 【无人车】用于无人地面车辆的路径跟踪算法(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现 1 概述 无人驾驶技术是当前社会的热门技术之一 无人
  • 【Unity&UGUI&Shader】创建材质球Material&代码控制更换物体材质球

    UGUI Unity Graphical User Interface 简称 UGUI 又称图形用户接口 如何创建材质球 NGUI Next generation GUI 下一代图形用户接口 Assets Create Material如下
  • 泛型,序列化

    何为泛型 1 JDK1 5以后推出的一种新的参数化的类型 2 通常可以理解为一种一种编译类型 在运行时无效 3 类型生活中的标签 为什么使用泛型 1 约束类中属性类型 方法参数类型 方法返回值类型 2 提高运行时性能 List s new
  • 西门子PLC的TCP通讯(不同项目下)②--TRCV_C指令

    西门子PLC的TCP通讯 不同项目下 TRCV C指令 上期主要了解了TSEND C指令的各项参数的意义 隐藏参数LEN等可以默认 本期将了解另一个配套组合指令块TRCV C 这是个接收指令块 大概呢跟发送指令TSEND C差不多 1 0
  • pinia的基本使用

    npm install pinia 安装pinia import createPinia from pinia app use createPinia main js中使用pinia 新建一个store文件夹 类似于vuex src sto
  • 前端技术搭建扫雷小游戏(内含源码)

    The sand accumulates to form a pagoda 写在前面 功能介绍 页面搭建 样式设置 逻辑部分 写在前面 上周我们实通过前端基础实现了贪吃蛇游戏 今天还是继续按照我们原定的节奏来带领大家完成一个游戏 功能也比较
  • Python机器学习笔记:深入理解Keras中序贯模型和函数模型

    先从sklearn说起吧 如果学习了sklearn的话 那么学习Keras相对来说比较容易 为什么这样说呢 我们首先比较一下sklearn的机器学习大致使用流程和Keras的大致使用流程 sklearn的机器学习使用流程 from skle
  • Linux下minicom的配置和使用方法

    安装配置minicom lsmod grep usbserial 如果直接使用串口线 而没有用到USB转串口设备 此步可以跳过 如果有usbserial 说明系统支持USB转串口 安装minicom Fedora自带有minicom 此步可
  • shell 守护进程之 mongodb

    场景 因为某些原因 mongodb 挂掉了 需要重启 思路 写个守护进程脚本 每分钟查看mongodb状态 这里查看mongodb进程是否存在 如果挂掉就重启 执行 1 创建sh文件 mkdir p data wwww guard mong
  • it技术交流社区与学习资料的网站大全

    点击上方蓝字 优派编程 选择 加为星标 第一时间关注原创干货 对国内技术社区 博客园 https www cnblogs com 掘金 https juejin cn 思否 https segmentfault com 开源中国 https
  • Ubuntu18.04升级到20.04

    升级方式 命令行升级 正常情况下使用如下命令即可 sudo do release upgrade 当提示如下错误信息时 得先升级本地软件包 Please install all available updates for your rele
  • 区块链的简单实现

    区块链的简单实现 什么是区块链 块结构 创世区块 hash 验证块的有效性 记录数据 从其他节点接收一个块 编写测试代码 测试结果 完整代码 什么是区块链 一个维护着一个持续增长的有序数据记录列表的这么一个分布式数据库 下面我将简单用nod
  • 玩转X-CTR100 l STM32F4 l U-Blox NEO-6M GPS卫星定位-nmealib解码库移植解码

    我造轮子 你造车 创客一起造起来 塔克创新资讯 塔克社区 www xtark cn 塔克博客 www cnblogs com xtark 本文介绍X CTR100控制器 扩展GPS卫星定位模块 型号为GY GPS6MV2 使用U BLOX
  • 数据库连接自动断开:CJCommunicationsException

    报错信息 com mysql cj exceptions CJCommunicationsException The last packet successfully received from the server was 99 117
  • JavaSE基础知识(个人总结)

    声明 1 本文为我的个人复习总结 并非那种从零基础开始普及知识 内容详细全面 言辞官方的文章 2 由于是个人总结 所以用最精简的话语来写文章 3 若有错误不当之处 请指出 基础 杂记 JRE JVM 常用类库 JDK JRE 诸多工具 如j