个人参考

250 阅读21分钟

整篇文章都是摘抄,如有侵权,还望告知

快速排序:


package _1;

import java.util.Arrays;
import java.util.Scanner;

public class One {

	public static void main(String[] args) {
		int[] arr = {21,25,63,85,56,42,72};
		quickSort(arr);
		System.out.println(Arrays.toString(arr));
	}

	public static void quickSort(int[] arr) {
		quickSort(arr,0,arr.length-1);}
	public static void quickSort(int[] arr,int low,int high) {
		if (low<high) {
			int index = partQuickSort(arr,low,high);
			quickSort(arr,low,index-1);
			quickSort(arr,index+1,high);}}
	public static int partQuickSort(int[] arr,int low,int high) {
		int x = arr[low];
		while(low<high) {
			while(x<arr[high]&&low<high) {
				high--;}
			if (low<high) {
				arr[low] = arr[high];
				low++;}
			while(x>arr[low]&&low<high) {
				low++;}
			if (low<high) {
				arr[high] = arr[low];
				high--;}}
		arr[low] = x;
		return low;
	}
}

工厂模式:

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

应用实例:

  • 您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现
  • Hibernate 换数据库只需换方言和驱动就可以。

优点:

  • 一个调用者想创建一个对象,只要知道其名称就可以了。
  • 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
  • 屏蔽产品的具体实现,调用者只关心产品的接口。

缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

1.创建一个接口:
public interface Shape {
   void draw();
}
2.创建实现接口的实体类
public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}
public class Square implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}
public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}
3.创建一个工厂,生成基于给定信息的实体类的对象
public class ShapeFactory {
    
   //使用 getShape 方法获取形状类型的对象
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }        
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      return null;
   }
}
4.使用该工厂,通过传递类型信息来获取实体类的对象
public class FactoryPatternDemo {
 
   public static void main(String[] args) {
      ShapeFactory shapeFactory = new ShapeFactory();
 
      //获取 Circle 的对象,并调用它的 draw 方法
      Shape shape1 = shapeFactory.getShape("CIRCLE");
 
      //调用 Circle 的 draw 方法
      shape1.draw();
 
      //获取 Rectangle 的对象,并调用它的 draw 方法
      Shape shape2 = shapeFactory.getShape("RECTANGLE");
 
      //调用 Rectangle 的 draw 方法
      shape2.draw();
 
      //获取 Square 的对象,并调用它的 draw 方法
      Shape shape3 = shapeFactory.getShape("SQUARE");
 
      //调用 Square 的 draw 方法
      shape3.draw();
   }
}
5.执行程序,输出结果
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.

单例模式:

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:

  • 单例类只能有一个实例。
  • 单例类必须自己创建自己的唯一实例。
  • 单例类必须给所有其他对象提供这一实例。

应用实例:

  • 一个班级只有一个班主任。
  • Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。
  • 一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。

优点:

  • 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
  • 避免对资源的多重占用(比如写文件操作)。

缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

使用场景:

  • 要求生产唯一序列号。
  • WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
  • 创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

注意事项:getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。

1.创建一个 Singleton 类
public class SingleObject {
 
   //创建 SingleObject 的一个对象
   private static SingleObject instance = new SingleObject();
 
   //让构造函数为 private,这样该类就不会被实例化
   private SingleObject(){}
 
   //获取唯一可用的对象
   public static SingleObject getInstance(){
      return instance;
   }
 
   public void showMessage(){
      System.out.println("Hello World!");
   }
}
2.从 singleton 类获取唯一的对象
public class SingletonPatternDemo {
   public static void main(String[] args) {
 
      //不合法的构造函数
      //编译时错误:构造函数 SingleObject() 是不可见的
      //SingleObject object = new SingleObject();
 
      //获取唯一可用的对象
      SingleObject object = SingleObject.getInstance();
 
      //显示消息
      object.showMessage();
   }
}
3.执行程序,输出结果:
Hello World!

单例模式的几种实现方式:

1.懒汉式,线程不安全

是否 Lazy 初始化:是

是否多线程安全:否

实现难度:易

描述:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。 这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。

public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
  
    public static Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
}

2.懒汉式,线程安全

是否 Lazy 初始化:是

是否多线程安全:是

实现难度:易

描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。

优点:第一次调用才初始化,避免内存浪费。

缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。 getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)

public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
    public static synchronized Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
}

3、饿汉式

是否 Lazy 初始化:否

是否多线程安全:是

实现难度:易

描述:这种方式比较常用,但容易产生垃圾对象。

优点:没有加锁,执行效率会提高。

缺点:类加载时就初始化,浪费内存。 它基于 classloader 机制避免了多线程的同步问题,不过,instance 在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用 getInstance 方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化 instance 显然没有达到 lazy loading 的效果

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
    return instance;  
    }  
}

4、双检锁/双重校验锁(DCL,即 double-checked locking)

JDK 版本:JDK1.5 起

是否 Lazy 初始化:是

是否多线程安全:是

实现难度:较复杂

描述:这种方式采用双锁机制,安全且在多线程情况下能保持高性能。 getInstance() 的性能对应用程序很关键。

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
}

5、登记式/静态内部类

是否 Lazy 初始化:是

是否多线程安全:是

实现难度:一般

描述:这种方式能达到双检锁方式一样的功效,但实现更简单。对静态域使用延迟初始化,应使用这种方式而不是双检锁方式。这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。 这种方式同样利用了 classloader 机制来保证初始化 instance 时只有一个线程,它跟第 3 种方式不同的是:第 3 种方式只要 Singleton 类被装载了,那么 instance 就会被实例化(没有达到 lazy loading 效果),而这种方式是 Singleton 类被装载了,instance 不一定被初始化。因为 SingletonHolder 类没有被主动使用,只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance。想象一下,如果实例化 instance 很消耗资源,所以想让它延迟加载,另外一方面,又不希望在 Singleton 类加载时就实例化,因为不能确保 Singleton 类还可能在其他的地方被主动使用从而被加载,那么这个时候实例化 instance 显然是不合适的。这个时候,这种方式相比第 3 种方式就显得很合理

public class Singleton {  
    private static class SingletonHolder {  
    private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
    return SingletonHolder.INSTANCE;  
    }  
}

6、枚举

JDK 版本:JDK1.5 起

是否 Lazy 初始化:否

是否多线程安全:是

实现难度:易

描述:这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。 这种方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。不过,由于 JDK1.5 之后才加入 enum 特性,用这种方式写不免让人感觉生疏,在实际工作中,也很少用。 不能通过 reflection attack 来调用私有构造方法。

public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
}

经验之谈:一般情况下,不建议使用第 1 种和第 2 种懒汉方式,建议使用第 3 种饿汉方式。只有在要明确实现 lazy loading 效果时,才会使用第 5 种登记方式。如果涉及到反序列化创建对象时,可以尝试使用第 6 种枚举方式。如果有其他特殊的需求,可以考虑使用第 4 种双检锁方式

装饰器模式:

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能

应用实例:

  • 孙悟空有 72 变,当他变成"庙宇"后,他的根本还是一只猴子,但是他又有了庙宇的功能。
  • 不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。

优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点:多层装饰比较复杂。

使用场景:

  • 扩展一个类的功能。
  • 动态增加功能,动态撤销。

注意事项:可代替继承

1.创建一个接口:
public interface Shape {
   void draw();
}
2.创建实现接口的实体类
public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Shape: Rectangle");
   }
}
public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Shape: Circle");
   }
}
3.创建实现了 Shape 接口的抽象装饰类
public abstract class ShapeDecorator implements Shape {
   protected Shape decoratedShape;
 
   public ShapeDecorator(Shape decoratedShape){
      this.decoratedShape = decoratedShape;
   }
 
   public void draw(){
      decoratedShape.draw();
   }  
}
4.创建扩展了 ShapeDecorator 类的实体装饰类
public class RedShapeDecorator extends ShapeDecorator {
 
   public RedShapeDecorator(Shape decoratedShape) {
      super(decoratedShape);     
   }
 
   @Override
   public void draw() {
      decoratedShape.draw();         
      setRedBorder(decoratedShape);
   }
 
   private void setRedBorder(Shape decoratedShape){
      System.out.println("Border Color: Red");
   }
}
5.使用 RedShapeDecorator 来装饰 Shape 对象
public class DecoratorPatternDemo {
   public static void main(String[] args) {
 
      Shape circle = new Circle();
      ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
      ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
      //Shape redCircle = new RedShapeDecorator(new Circle());
      //Shape redRectangle = new RedShapeDecorator(new Rectangle());
      System.out.println("Circle with normal border");
      circle.draw();
 
      System.out.println("\nCircle of red border");
      redCircle.draw();
 
      System.out.println("\nRectangle of red border");
      redRectangle.draw();
   }
}
6.执行程序,输出结果:

Circle with normal border
Shape: Circle

Circle of red border
Shape: Circle
Border Color: Red

Rectangle of red border
Shape: Rectangle
Border Color: Red

抽象工厂模式:

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象

应用实例:工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产品)、时尚装(成套,一系列具体产品),甚至对于一个家庭来说,可能有商务女装、商务男装、时尚女装、时尚男装,这些也都是成套的,即一系列具体产品。假设一种情况(现实中是不存在的,要不然,没法进入共产主义了,但有利于说明抽象工厂模式),在您的家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然要从这个衣柜中取出了。用 OOP 的思想去理解,所有的衣柜(具体工厂)都是衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。

优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

使用场景: 1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。

注意事项:产品族难扩展,产品等级易扩展。

1.为形状创建一个接口
public interface Shape {
   void draw();
}
2.创建实现接口的实体类
public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}
public class Square implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}
public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}
3.为颜色创建一个接口
public interface Color {
   void fill();
}
4.创建实现接口的实体类
public class Red implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Red::fill() method.");
   }
}
public class Green implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Green::fill() method.");
   }
}
public class Blue implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Blue::fill() method.");
   }
}
5.为 Color 和 Shape 对象创建抽象类来获取工厂
public abstract class AbstractFactory {
   public abstract Color getColor(String color);
   public abstract Shape getShape(String shape) ;
}
6.创建扩展了 AbstractFactory 的工厂类,基于给定的信息生成实体类的对象
public class ShapeFactory extends AbstractFactory {
    
   @Override
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }        
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      return null;
   }
   
   @Override
   public Color getColor(String color) {
      return null;
   }
}
public class ColorFactory extends AbstractFactory {
    
   @Override
   public Shape getShape(String shapeType){
      return null;
   }
   
   @Override
   public Color getColor(String color) {
      if(color == null){
         return null;
      }        
      if(color.equalsIgnoreCase("RED")){
         return new Red();
      } else if(color.equalsIgnoreCase("GREEN")){
         return new Green();
      } else if(color.equalsIgnoreCase("BLUE")){
         return new Blue();
      }
      return null;
   }
}
7.创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂
public class FactoryProducer {
   public static AbstractFactory getFactory(String choice){
      if(choice.equalsIgnoreCase("SHAPE")){
         return new ShapeFactory();
      } else if(choice.equalsIgnoreCase("COLOR")){
         return new ColorFactory();
      }
      return null;
   }
}
8.使用 FactoryProducer 来获取 AbstractFactory,通过传递类型信息来获取实体类的对象
public class AbstractFactoryPatternDemo {
   public static void main(String[] args) {
 
      //获取形状工厂
      AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
 
      //获取形状为 Circle 的对象
      Shape shape1 = shapeFactory.getShape("CIRCLE");
 
      //调用 Circle 的 draw 方法
      shape1.draw();
 
      //获取形状为 Rectangle 的对象
      Shape shape2 = shapeFactory.getShape("RECTANGLE");
 
      //调用 Rectangle 的 draw 方法
      shape2.draw();
      
      //获取形状为 Square 的对象
      Shape shape3 = shapeFactory.getShape("SQUARE");
 
      //调用 Square 的 draw 方法
      shape3.draw();
 
      //获取颜色工厂
      AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
 
      //获取颜色为 Red 的对象
      Color color1 = colorFactory.getColor("RED");
 
      //调用 Red 的 fill 方法
      color1.fill();
 
      //获取颜色为 Green 的对象
      Color color2 = colorFactory.getColor("Green");
 
      //调用 Green 的 fill 方法
      color2.fill();
 
      //获取颜色为 Blue 的对象
      Color color3 = colorFactory.getColor("BLUE");
 
      //调用 Blue 的 fill 方法
      color3.fill();
   }
}
9.执行程序,输出结果:

Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside Red::fill() method.
Inside Green::fill() method.
Inside Blue::fill() method.

IO流:

集合:

Vector:

Stack:

Arraylist:

Linkedlist:

HashSet:

LinkedHashSet:

TreeSet:

Map:

HashMap:

HashMap 和 Hashtable 有什么区别?

  • 存储:HashMap 允许 key 和 value 为 null,而 Hashtable 不允许。
  • 线程安全:Hashtable 是线程安全的,而 HashMap 是非线程安全的。
  • 推荐使用:在 Hashtable 的类注释可以看到,Hashtable 是保留类不建议使用,推荐在单线程环境下使用 HashMap 替代,如果需要多线程使用则用 ConcurrentHashMap 替代

实现原理:

HashMap 基于 Hash 算法实现的,我们通过 put(key,value)存储,get(key)来获取。当传入 key 时,HashMap 会根据 key. hashCode() 计算出 hash 值,根据 hash 值将 value 保存在 bucket 里。当计算出的 hash 值相同时,我们称之为 hash 冲突,HashMap 的做法是用链表和红黑树存储相同 hash 值的 value。当 hash 冲突的个数比较少时,使用链表否则使用红黑树[ 链表长度大于8时转换为红黑树]

Java8新特性:

Lambda表达式: 主要是用来替换匿名内部类 根据匿名内部类的参数返回值形式来使用 首先要明确只有函数式接口(接口里只有一个抽象方法)才可以用lambda表达式 : @FunctionalInterface标志的接口

1无参 无返回值:() -> 方法体
2需要一个参数 无返回值:(变量(无需类型)) -> 方法体(方法体内直接使用前面的变量); 
			若只需要一个参数的时候小括号可以省略  变量   -> 方法体(方法体内直接使用前面的变量); 
3两个或以上参数 多条执行语句 并且有返回值:
			(参数1,参数2) ->{
					语句。。。
					语句。。。
					return 。。。。
			}
			如果只是单纯地return一个结果 并没有其他的语句 可以写成	(参数1,参数2) ->  return 后面的语句;

java内置了四大核心函数式接口:
		Consumer 有参数无返回值
		Supplier 无参数有返回值
		Function 有参数有返回值
		Predicate 有参数有固定布尔类型返回值 
		我们也可以自己写一个接口~

方法引用:对Lambda表达式做更简洁的实现

对象名::方法名
		(t)-> System.out.println(t);
		有参数无返回值的 跟println方法一样 所以可以简写成:
		PrintStream s = System.out
		s::println;

类名::方法名
		(o1,o2) - >Integer.compare(o1,o2)     可以转换成
		Integer::compare

对象的类名::方法名
		(e)  ->  e.do();        此时e是一个自定义对象  则可以转换成
		自定义类::do;

构造器的引用:
			构造器参数列表要与接口中抽象方法参数列表一致!
			方法的返回值即为构造器对应类的对象  (当然也需要只有一条语句 并且是return语句  而且需要自定义类有相对应的构造器)
			(t) -> new 自定义类名(t)
			可以简写成:
			方法的返回类名::new

数组引用:
	           (t)  -> new Integer[t]
	           可以简写成:      
	           Integer[] :: new

lambda详解链接:blog.csdn.net/qq_40976761…

StreamAPI:

集合创建流
ArrayList list  = new ArrayList();
list.stream() 顺序流
list.parallelStream()并行流

数组创建流
Arrays.stream(数组);

通过Stream.of创建
Stream.of(3,4,5,6,7);

Stream.iterate(初始值,lambda表达式).limit().forEach(lambda表达式)   创造无限流  (limit限制输出 forEach遍历每一个可以进行输出)

Stream.generate(lambda表达式).limit(2).forEach(lambda表达式);  也是创造无限流

===========================Stream强大的功能从此开始  partone===================================
1 filter(Predicate p)  过滤实现了Predicate接口的元素
list.stream().filter(lambda表达式).foreach(lambda表达式 可进行输出);

2limit 截断流 使元素不超过指定的数量

3skip(n) 跳过元素 返回一个扔掉了前n个元素的流

4distinct() 通过流所生成元素的hashCode() 和 equals() 去除重复的元素
===========================Stream强大的功能从此开始  parttwo===================================
1 map 接受一个函数作为参数 该函数会被应用到每一个元素上
list.stream().map(lambda表达式).forEach()

2 flatMap() 跟map的区别在于可以对每一个字符做操作 例如:在每一个字符后面加?
list.stream().flatMap((t) ->{
		List<String> list = new ArrayLIst<>();
		for(int i =0; i < t.getName().length(); i++){
		list.add(t.getName().charAt(i)+"?")
		}
		return list.stream();
}).forEach(System.out::println)

3sorted() 自然排序  要实现comparble重写compareto
list.stream().sorted().forEach()
	
	sorted(Compartor com ) 定制排序


4allMatch(Predicate)  检查是否匹配所有元素
  anyMatch 检查是否至少匹配一个元素
  noneMatch 检查是否没有匹配的元素
  findFirst 返回第一个元素
  findAny  返回任意一个元素
  count() 返回流中元素的总个数
  max(Compartor c) 返回流中最大值

5reduce
list.stream().map((t) - > t.getAge()). reduce(0,(x,y) - > x + y );  计算总和 需要和map一起用

6Collect
返回一个list集合:
LIst(String) collect = list.stream().map((t) -> t.getName()).collect(Collectiors.toList());

将list转换成map:结果为以level分组的map集合
Map<Byte, List<String>> levelList = list.stream()
                .collect(groupingBy(ProductBottle::getLevel, mapping(ProductBottle::getQrcode, toList())));

interface:

  • 接口里面可以定义方法 (默认都是public)

    • 静态方法 public static void do(){ ...} 调用:接口名.静态方法
    • 默认方法 public default void do(){ ...} 调用:实现类的对象.对应的方法(实现类对象优先调用自己本类的重写方法~)
    • 原来的抽象方法
  • 如果实现类重写了两个接口有同名方法,那么实现类必须自己重写这个方法

  • 在实现类的方法中调用接口的方法: * 默认方法: 接口名.super.默认方法名();

注解的新特性:

  • 重复注解: 可以将注解对同一个被注解的对象重复使用
   @Repeatable(value = annotations.class)
	@interface  annotation{
	}

	@interface annotations{
	    annotation[] value();
	}
  • 类型注解:可以在变量前(成员变量或者形参)加注解,跟框架里注解的使用一样 给自己定义的注解上面加元注解:
@target(value = {ElementType.TYPE_USE,ElementType.TYPE_PARAMETER})
		ElementType.TYPE_USE表示任何类型的变量前都可以加注解
		ElementType.TYPE_PARAMETER表示可以在变量前加注解

新日期:

LocalDate对象的使用:

	静态方法:   
     now 静态方法根据当前时间创建对象 
     			可以通过ZoneId.getAvailableZoneIds();获取每一个地域对应的字符串  传入now参数中(ZoneId.of("区域字符串"))
     			ZoneDateTime.now()获取本地时区的时间
     of   根据指定的日期/时间创建对象
    例子:
    LocalDate localDate = LocalDate.now();
    LocalTime  	localTime		= LocalDate.now();
    LocalDateTime  	localDateTime			=LocalDateTime.now();

     普通成员方法:
     获取日期和时间getDayOfMonth()      getDayOfYear()      getHour()      getDayOfWeek()      getMinute()      getYear()     
     修改日期和时间: withDayOfYear(300)  根据原本的localDate生成新的对象,原本的localDate对象并没有被改变~~
     增加或者减少几天 几周:plus()     minus()
Instance对象的使用:
	静态方法:
	now()返回默认UTC时区的Instant类对象
	ofEpochMilli(毫秒数);1970年+这个毫秒数获取定义的时间
	成员方法:
	toEpochMilli()返回一个时间戳
	atOffset(ZoneOffset.ofHours(8))修改对应的时间
DateTimeFormatter对象的使用: 定义时间的格式  可以直接类名。静态变量返回指定格式化的对象
	静态方法:
	ofPattern("格式")  指定模式进行格式化
	ofLocalizedDate(Formate.FULL)返回本地格式的对象
 	成员方法:
 	format将时间转换成字符串
 	parse将字符串转换成时间
Duration对象的使用:计算两个时间的差值
	静态方法:
	between(LocalTime1,LocalTime2)
	成员方法:
	总共差的秒数是全部成员方法相加:
    getSeconds()  getNano()
Period对象的使用:计算两个日期的差值
	getYears() getDays()  getMonths()

Optional:为了解决空指针异常:

  • Optional.empty(): 创建一个空的对象
  • Optional.of("AAA"); 将AAA放入容器中 get()方法获取容器中的数据
  • Optional.ofNullable(null) 在调用成员方法orElse("asd"); 输出此对象 如果是null就输出后者 如果不是null就输出前者~~~ 成员方法isPresent()判断里面是否为空返回布尔值