JAVA中的内部类,Lambda表达式以及Stream流

1.内部类

1.什么是内部类

  把类定义在另一个类的内部,该类就被称为内部类。
  如果在类 Outer 的内部再定义一个类 Inner,此时类 Inner 就称为内部类(或称为嵌套类),而类 Outer 则称为外部类(或称为宿主类)。

2.内部类的分类

  内部类一般来说包括这四种:

    1.成员内部类
    2.静态内部类
    3.局部内部类
    4.匿名内部类


   1.成员内部类

   就是位于外部类成员位置的类
   特点:可以使用外部类中所有的成员变量和成员方法(包括private的)

class Outer {
      private int age = 20;
     
      class Inner {
          public void show() {
              System.out.println(age);
          }
      }
}



 class Test {
      public static void main(String[] ages) {
      Outer.Inner oi = new Outer().new Inner();
          oi.show();
      }
  }

  private修饰内部类
  如果我们的内部类不想轻易被任何人访问,可以选择使用private修饰内部类,这样我们就无法通过创建对象的方法来访问,想要访问只需要在外部类中定义一个public修饰的方法,间接调用。这样做的好处就是,我们可以在这个public方法中增加一些判断语句,起到数据安全的作用。

class Outer {
      private class Inner {
          public void show() {
              System.out.println(“密码备份文件”);
          }
      }
      //使用getXxx()获取成员内部类,可以增加校验语句(文中省略)
      public Inner getInner() {
          return new Inner();
      }
     }
    public static void main(String[] args) {
          Outer outer = new Outer();
          Outer.Inner inner = outer.getInner();
          inner.show();
      }

2.静态内部类

  这种被 static 所修饰的内部类,按位置分,属于成员内部类,但也可以称作静态内部类,也常叫做嵌套内部类.不能使用外部类的非static成员变量和成员方法。

​
public class Outter {
      int age = 10;
      static int  age2 = 20;
      public Outter() {       
      }
      
      static class Inner {
          public void method() {
              System.out.println(age);//错误
              System.out.println(age2);//正确
          }
      }
  }

​

public class Test {
      public static void main(String[] args)  {
          Outter.Inner inner = new Outter.Inner();
          inner.method();
      }
  }

3.局部内部类

  局部内部类——就是定义在一个方法或者一个作用域里面的类。
  特点:主要是作用域发生了变化,只能在自身所在方法和属性中被使用。

class Outer {
      private int age = 20;
      public void method() {
          final int age2 = 30;
          class Inner {
              public void show() {
                  System.out.println(age);
                  //从内部类中访问方法内变量age2,需要将变量声明为最终类型。
                  System.out.println(age2);
              }
          }
                    Inner i = new Inner();
                            i.show();

4.匿名内部类

一个没有名字的类,是内部类的简化写法

interface Inner {
      public abstract void show();
}  ​
  class Outer {
      public void method(){
          new Inner() {
              public void show() {
                  System.out.println("HelloWorld");
              }
          }.show();
      }
  }


class Test {
      public static void main(String[] args)  {
          Outer o = new Outer();
                   o.method();
      }
  }


3. 内部类的意义

  内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号。
  内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否为 private 的。
  内部类声明成静态的,就不能随便访问外部类的成员变量,仍然是只能访问外部类的静态成员变量 。

意义:

1.封装性
作为一个类的编写者,我们很显然需要对这个类的使用访问者的访问权限做出一
定的限制,我们需要将一些我们不愿意让别人看到的操作隐藏起来.

2.实现多继承

2.Lambda表达式

1.Lambda表达式的概念

Lambda 表达式是一个匿名函数,我们可以把 lambda 表达式理解为一段可以传递的代码(将代码段像数据一样传递)。使用它可以写出更简洁, 更灵活的代码。作为一种更紧凑的代码风格,使 java 语言的表达式能力得到的提升。


Lambda 表达式的本质只是一个"语法糖",由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能。

2.Lambda 表达式的结构

    Lambda 表达式可以具有零个,一个或多个参数。
 可以显式声明参数的类型,也可以由编译器自动从上下文推断参数的类型。
例如 (int a,int b)与 (a,b)相同。
 参数用小括号括起来,用逗号分隔。例如 (a, b) 或 (int a, int b) 或 (Stringa, int b, float c)。
 空括号用于表示一组空的参数。例如 () -> 42。
 当有且仅有一个参数时,如果不显式指明类型,则不必使用小括号。例如 a -> return a*a。
 Lambda 表达式的正文可以包含零条,一条或多条语句。
 如果 Lambda 表达式的正文只有一条语句,则大括号可不用写,且表达式的返回值类型要与匿名函数的返回类型相同。
 如果 Lambda 表达式的正文有一条以上的语句必须包含在大括号(代码块)中,且表达式的返回值类型要与匿名函数的返回类型相同。
Java 中的 Lambda 表达式通常使用 (argument) -> {body}语法书写

new Thread(()->{
            boolean flag=true;
            while (flag){
                try {

                    String s=dataInputStream.readUTF();
                    jTextArea.append("\n"+s+"\n");

                } catch (IOException e) {
                    e.printStackTrace();
                    flag=false;
                }
            }

        }).start();

4.什么是功能接口(Functional interface)

Lambda 表达式只支持函数式接口 也就是只有一个抽象方法的接口.功能接口是 java 8 中的新增功能,它们只允许一个抽象方法。这些接口也称为单抽象方法接口。Java 8 也引入了一个注释,即@FunctionalInterface,当你注释的接口违反了 Functional Interface 的契约时,它可以用于编译器级错误。

功能接口只能有一个抽象方法。如果我们尝试在其中添加一个抽象方法,则会抛出编译时错误。

3.Stream流

1.什么是 Stream?

Stream 是 Java8 的新特性,它允许你以声明式的方式处理数据集合,可以把它看作是遍历数据集的高级迭代器。此外与 stream 与 lambada 表达示结合后编码效率与大大提高,并且可读性更强。
要澄清的是 java8 中的 stream 与 InputStream 和 OutputStream 是完全不同的概念.

2.什么是流呢? 

简单的定义,就是“从支持数据处理操作的源,生成的元素序列”。
元素列表:和集合一样,流也提供了一个接口,访问特定元素类型的一组有序值。
数据源 :获取数据的源,比如集合。
数据处理操作 :流更偏向于数据处理和计算,比如 filter、map、find、sort 等。
简单来说,我们通过一个集合的 stream 方法获取一个流,然后对流进行一系列流操作,最后再构建成我们需要的数据集合。

3.获取流

使用 Collection 接口下的 stream()
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();


使用 Arrays 中的 stream() 方法,将数组转成流
Integer[] nums = new Integer[10];
Stream<Integer> stream = Arrays.stream(nums);


使用 Stream 中的静态方法:of()
Stream<Integer> stream = Stream.of(1,2,3,4,5,6);


使用 BufferedReader.lines() 方法,将每行内容转成流
BufferedReader reader=new BufferedReader(new FileReader("stream.txt"));
Stream<String> lineStream = reader.lines();

4.流操作


流操作可以分为两类:中间操作和终端操作。回看之前的代码:

List<Apple> apples = applestore
.stream() 获得流
.filter(a -> a.getColor().equals("red")) 中间操作
.collect(Collectors.toList()); 终端操作

中间操作
filter:过滤流中的某些元素,
sorted(): 自然排序,流中元素需实现 Comparable 接口
distinct: 去除重复元素
limit(n): 获取 n 个元素
skip(n): 跳过 n 元素,配合 limit(n)可实现分页
map(): 将其映射成一个新的元素


终端操作
forEach: 遍历流中的元素
toArray:将流中的元素倒入一个数组
Min:返回流中元素最小值
Max:返回流中元素最大值
count:返回流中元素的总个数
Reduce:所有元素求和
anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足条件则返
回 true,否则返回 false
allMatch:接收一个 Predicate 函数,当流中每个元素都符合条件时才返
回 true,否则返回 false
findFirst:返回流中第一个元素
collect:将流中的元素倒入一个集合,Collection 或 Map

public static void main(String[] args) {
//         Stream.of(1, 2, 6, 3, 4, 5)
//                .filter((a) -> {
//                    return a > 3;
//                })//过滤,中间操作
//                .sorted((a, b) -> {
//                    return b - a;
//                })//排序(倒序),中间操作
//                .distinct()//去重
//                 .forEach(a->{
//                     System.out.println(a);
//                 });//终端操作,遍历,中间操作
         Stream.of(1, 2, 6, 3, 4, 5)
                .skip(2)//跳过n个元素
                 .limit(2)//取出n个元素
                 .forEach(a->{
                     System.out.println(a);
                 });


    }
}
    public static void main(String[] args) {

//    Integer i=    Stream.of(1,2,3,4,6,5)
//                .max((a,b)->{
//                    return a-b;
//                }).get();
//        System.out.println(i);
//    }


//       Integer i=      Stream.of(1,2,3,4,6,5)
//                     .min((a,b)->{
//
//                       return a-b;
//    }).get();
//        System.out.println(i);


//       Long i= Stream.of(1,2,3,4,6,5)
//                .count();
//        System.out.println(i);

//     Integer sum=   Stream.of(1,2,3,4,6,5)
//                .reduce((a,b)->{
//                    return a+b;
//                }).get();
//        System.out.println(sum);

    boolean a=    Stream.of(1,2,3,4,6,5)
                .anyMatch((b)->{
                    return b>3;
                });
        System.out.println(a);
}}

猜你喜欢

转载自blog.csdn.net/weixin_64189867/article/details/131563573