整篇文章都是摘抄,如有侵权,还望告知
快速排序:
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()判断里面是否为空返回布尔值