java(匿名函数、方法引用、Stream、内存分配以及遇到的问题)

一、java一个文件可以写多个类吗?

1、在一个.java文件中可以有多个同级类, 其修饰符只可以public/abstract/final/和无修饰符
2、public修饰的只能有一个,且必须要与文件名相同;
3、该文件同级的类之间可以互相调用,但是除了public的类,其他不能够在其他文件调用
     在一个.java文件中由类/Enum/接口/Anontation其中至少一个类型组成。
     单独一个方法/变量不能独自存在与文件中,所以公用方法的封装也是做成类方法。
     原因是java是类加载机制,需要编译一个java文件成多个class文件,当类来使用。
     用javac 编译这个.java文件的时候,它会给每一个类生成一个.class文件

二、乱码问题,比如.properties配置文件

file——settings——editor——file encodings页面,都设置为utf-8

三、匿名函数

1、lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)
2、在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量

实现步骤
1、先申明只有一个抽象方法的接口;

    @FunctionalInterface  // 要求接口有且只有一个抽象方法
    interface Demo {
        int test(int a, int b);
    }

2、写一个函数,函数中可以写很多其他额外的操作

    public static Integer handler(int a,int b,Demo demo){
        return demo.test(a,b);
    }

3、使用函数并实现接口

int result=handler(1, 2, (z,x)->z );
System.out.println(result);

如果没有第二步,则使用方式如下,第二步相当于已经做了一部分操作。

Demo d = (int a, int b) -> a + b;
int result=d.test(1,2);
System.out.println(result);

java8内置的四大函数式接口
1、消费型接口, 有输入无返回
  Consumer<T>:
    void accept(T t)
   实现例子:m-> System.out.println(m);
2、供给型接口,无输入有返回
  Supplier<T>:
    T get()
     实现例子:()-> (int)(Math.random()*100);
3、函数型接口,有输入有返回
  Function<T,R>:
    R apply(T t)
     实现例子:(a,b)-> a+b
4、断言型接口, 有输入返回布尔
  Predicate<T>:
    boolean test(T t)
     实现例子:a-> a>0

四、方法引用

这个搞得我脑壳疼,还是不明白

找到的定义是这样的:

如果一个方法的调用中,这个方法给接口提供的参数和他接收的返回,和你现有某个实现完全一致,就可以进一步进行简化,称为方法引用

第二天搞明白了,看了廖雪峰的一个教程 https://www.liaoxuefeng.com/wiki/1252599548343744/1305207799545890

说实例方法有一个隐含的this参数,在实际调用的时候,第一个隐含参数总是传入this

五、Stream

https://www.runoob.com/java/java8-streams.html

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象.
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等.

 

 

六、java内存

Java把内存分成:栈内存,堆内存,方法区,本地方法区和寄存器等。
1、栈-Stack
  a、方法在栈中运行
  b、存放的都是局部变量(方法的参数、方法{}中的变量),方法体中的引用变量和基本类型的变量都在栈上,其他都在堆上
2、堆-Heap
  a、用来存放动态产生的数据,比如new出来的对象。
  b、成员变量存储在堆,对象的引用存储在栈。
  c、堆内存的东西都有地址值:16进制
  d、堆内存的数据,都有默认值,如下:
    整数      0
    浮点数     0.0
    字符     '\u0000'
    布尔     false
    引用类型   null
3、方法区
  1、储存.class相关信息,包含方法的信息。
     2、在Java虚拟机中,方法区是可供各线程共享的运行时内存区域
  在.class文件加载时,静态方法和非静态方法都会加载到方法区中,只不过要调用到非静态方法时需要先实例化一个对象,
  对象才能调用非静态方法。如果让类中所有的非静态方法都随着对象的实例化而建立一次,那么会大量消耗内存资源,
  所以才会让所有对象共享这些非静态方法,然后用this关键字指向调用非静态方法的对象
4、本地方法栈
与操作系统有关
5、寄存器
JVM内部虚拟寄存器,存取速度非常快,程序不可控制。

常量池、静态成员变量都在堆中
JVM为每个加载的类型维护一个常量池,常量池是这个类型用到的常量的集合。
存放字符串常量和基本类型常量(public static final)

https://blog.csdn.net/weixin_39801465/article/details/114870314 加载顺序和内存存放位置  https://blog.csdn.net/weixin_43513342/article/details/85043465
https://blog.csdn.net/yuan_qh/article/details/100851544
年轻代,用来存放新近创建的对象,尺寸随堆大小的增大和减小而相应的变化,连续空间;
老年代,里面的对象几乎个个都是从年轻代熬过来的,它们是不会那么容易就 “死掉” 了的,不连续的内存空间;
永久代,存放JVM运行时使用的类,永久代同样包含了Java SE库的类和方法,永久代并不是Java堆内存的一部分。
jdk1.7中的常量池确实是移到了堆中,同时在jdk1.8中移除整个永久代,取而代之的是一个叫元空间(Metaspace)的区域

posted @ 2021-05-20 14:34  whitewall  阅读(423)  评论(0)    收藏  举报