闲聊java

一、2021-03-02

第一章 、java语言简介

​ java是一门高级编程语言,诞生于1994年美国的贝尔实验室,由高斯林以及他的团队编写。

​ java的平台有JavaSE(java标准版)、JavaME(移动端)、JavaEE(企业版)。

​ 特性有:安全性、健壮性、移植性(跨平台)。

第二章、搭建java开发环境

JDK

​ 1、下载JDK1.8:JDK是java的开发工具包,包含javac编译命令、javadoc文档命令等

​ 2、安装 傻瓜式下一步。

​ 3、配置环境变量。

maven

​ setting.xml文件

<?xml version="1.0" encoding="utf-8"?>  
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">  
     
    <localRepository>/usr/local/repository</localRepository>    
    <mirrors>  
        <!-- mirror | Specifies a repository mirror site to use instead of a given repository. The repository that | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used | for inheritance and direct lookup purposes, and must be unique across the set of mirrors. | <mirror> <id>alimaven</id> <mirrorOf>central</mirrorOf> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/repositories/central/</url> </mirror>-->
	<mirror>
		<id>alimaven</id>
		<name>aliyun maven</name>
		<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
		<mirrorOf>central</mirrorOf>
	</mirror> 
    </mirrors> 
    <profiles>  
	<profile>
	    <id>spring plugins</id>
	    <activation>
		<jdk>spring plugins</jdk>
	    </activation>
	    <pluginRepositories>
		<pluginRepository>
		    <id>spring plugins</id>
		    <name>Spring plugins</name>
		    <url>https://maven.aliyun.com/repository/spring-plugin</url>
		    <layout>default</layout>
		    <snapshots>
		        <enabled>true</enabled>
		        <updatePolicy>daily</updatePolicy>
		    </snapshots>
		</pluginRepository>
	    </pluginRepositories>
	</profile>
    </profiles>    
    <!-- <activeProfiles> <activeProfile>nexus</activeProfile> </activeProfiles> -->
     
</settings>

IDEA

第三章、初识java开发

JavaEE

​ java企业级开发,涉及HTML5、CSS3、javascript、servlet、xml、jsp…tomcat

​ MVC模式:是一种设计思想,不是框架。主要是将各个模块分离,各司其职,为前后端分离奠定基础。

​ model1模式:model、view、controller全部在页面中处理。

​ model2模式:controller分离。

​ model:模型层。POJO、dao。

​ view:视图层。vue、jsp、html、css3…

​ controller:控制层。SpringMVC、Strust2,servlet…

Spring

​ 提供企业级开发的一站式解决方案,主要目的是简化开发,提高开发效率。

​ IOC(控制反转) 容器:提供了javaBean的装载容器。

​ AOP面向切面编程。

package test;

import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;

public class Test2 { 
    
    @Autowired
    private Date date;

    public static void main(String[] args) { 
        // IOC是一种思想。将new对象改为容器注入。
        Date date = new Date();
    }
}

SpringBoot

​ 实际上还是Spring,为了摆脱繁琐的配置文件而编写的框架,只需要少量的配置便可生成一个企业级的项目。

​ application.yml

​ application.properties

​ pom.xml

SpringMVC

控制层

MyBatis-Plus

​ 持久层框架。

第四章、java基本概念

JDK

​ java开发工具包,包含编译工具javac,运行工具java和java API库等

JRE

​ java运行环境,包含java运行环境所需的包。

JVM

​ java虚拟机。

第五章、java数据类型划分

四种基本数据类型

​ byte

​ short

​ int

​ long

布尔型 boolean

字符型 char

浮点型 float double

第六章、java运算符

+  -  *   /   &&  ||  !  &  >  <  

第七章、java程序逻辑控制

for

which

if

第八章、方法的定义及使用

public        static void main(String[] args) { }
全限定修饰词    保留字  返回值  方法名   参数        方法体
publicprotectprivate
不同包
同包
不同类
同类

二、2021-03-03

第1章 、类与对象

概述:是一类事物的总称,“万物皆对象”的抽象。可以理解为模板,按照这个模板制造具体的物体。

生成类的方式:

​ new User user = new User();

​ 反射 : 利用全限定性类名创建对象。Spring IOC容器就是利用反射创建对象。

​ 克隆 : 实现Cloneable接口,表示这个类可以被克隆。浅克隆:同一对象的指针指向多个名字。深克隆:重新制造对象。两个对象之间不存在关联。

​ 序列化: 跨网络间传递的信息。用于缓存。

关系:

​ 继承 子类 父类

1.封装 :将物体的属性(成员变量)和行为(成员方法)进行封装,只关注物体有哪些属性和哪些行为,并不关注行为的具体过程。

2.继承 :子类扩展父类的属性和行为的过程。private不能继承。体现java的扩展性。java属于单继承。

3.多态:不同实体对同一事物做出不同表现的行为。

对象

是类的具体个体。对象在堆内存分配运行所需的空间。

引用数据类型与基本数据类型最大的不同在于:引用数据类型需要内存的分配和使用。所以,关键字new的主要功能就是分配内存空间,也就是说,只要使用引用数据类型,就要使用关键字new来分配内存空间。

第2章 深入分析类和对象

栈内存里面存放基本类型的变量和对象的引用变量

堆内存里面存放new创建的对象和数组。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6ULFS3Jg-1615520177488)(/home/wf/Documents/java栈和堆.png)]

匿名对象

没有栈指向的堆内存空间就是匿名对象,而且只能使用一次,然后就被回收;

匿名内部类:不指定类名的内部类。一定程度上,后来JDK8的被lamda表达式代替。

第3章、this关键字

this关键字表示当前对象,或者当前对象的一个实例,通过this可以调用本对象的所有方法和属性。

1、当成员变量和局部变量重名,可以用关键字this区分。

2、this关键字也可以用于在构造函数中调用其他构造函数。但是,只能定义在构造函数的第一行,因为初始化动作要先执行。

3、this是属于对象的,不属于类。

第四章、static关键字

静态变量和静态方法

1、被 static 修饰的变量属于类变量,可以通过类名.类变量调用,而不需要 new 出一个类来。

2、被 static 修饰的方法属于类方法,可以通过类名.类方法调用,而不需要 new 出一个类来。

3、类变量和类方法属于类的静态资源,是实例之间共享的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kIUSt0Pc-1615520177492)(/home/wf/Pictures/static.png)]

1、静态方法能不能引用非静态资源?不能,new的时候才会产生的东西,对于初始化后就存在的静态资源来说,根本不认识它。

2、静态方法里面能不能引用静态资源?可以,因为都是类初始化的时候加载的,大家相互都认识。

3、非静态方法里面能不能引用静态资源?可以,非静态方法就是实例方法,那是new之后才产生的,那么属于类的内容它都认识。

static代码块

static { 
	a = 1;
}

类加载的时候执行一次。用于优化程序,提高系统的效率。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7here3lV-1615520177496)(/home/wf/Pictures/JVM.png)]

第五章、代码块

  1. 普通代码块。类中方法的方法体。
  2. 构造代码块。创建对象的时候执行的程序。
  3. static代码块。类加载的时候执行的程序。
  4. 同步代码块。多线程场景中使用的程序。synchronized(){}

第六章、面向对象案例分析

第七章、数组的定义与使用

// 申明的同时创建
int[] arr = new int[10];

// 先申明,且初始化
int[] arr1 = null;
// 再创建
arr1 = new int[20];


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a2AU8Ffq-1615520177499)(/home/wf/Documents/数组.png)]

数组经常会遇到数组越界的异常。当下标超出数组长度时,发生数组越界异常。

异常:程序在运行的过程中出现的问题。比如I/O异常、运行时异常。文件找不到异常,类转换异常、空指针异常,数学异常…

第八章、数据表与简单java类映射转换

1、 数据实体表设计 = 类的定义;

2、表中的字段 = 类的成员属性 ;

3、表的一行记录 = 类的一个实例化对象 ;

4、表的多行记录 = 对象数组 ;

5、表的外键关联 = 引用关联 ;

第十章、String类特点分析

  1. String 类不属于基本数据类型。存储字符串的引用类型,是固定长度的。final修饰,不可继承。

  2. 实例化形式:

    ​ 直接赋值:String str = “wangfei”;内存中有”wangfei”字符串,则不新建对象,若没有,则新建一个对象。

    ​ 构造方法实例化:String str = new String(“wangfei”);两个对象。

  3. 比较:使用equals(String str);基本数据类型使用 == 比较大小,引用类型用equals()比较。实际上equals()方法的内部还是使用 == 比较,但是封装类类型重写了该方法,比如Integer、String等。

  4. 面试题:请解释String类两种对象实例化方式的区别?
    (1)直接赋值:只会产生一个实例化对象,并且可以自动保存到对象池之中,以实现该字符串实例的重用。
    (2)构造方法:会产生两个实例化对象,并且不会自动入池,无法实现对象重用,但是可以使用intern()方法手工入池。

  5. Object 的equals()方法源码。

 public boolean equals(Object obj) { 
        return (this == obj);
    }

第十一章、String 类常用方法。

  1. length():返回字符串的长度。数组的长度是length属性,而字符串是length()方法。

  2. equals(String str) :比较两个字符串内容是否相等。

    ​ 基本数据类型 == 比较的是内容是否相等,而引用类型比较的是hashcode是否相等。

  3. charAt(int index):返回指定下标的字符。

  4. subString(int indexLength):截取字符串。

  5. split(String str):分割字符串。

第十二章、继承的定义与使用(extends关键字)

  1. java 只支持单继承。鉴于单继承这个缺点,java用内部类补充单继承的缺点。使用接口的多实现补充。
  2. 类继承是为了复用其他类的属性和方法(非private修饰的属性和方法)。
  3. 继承的定义与使用(面向对象的第二大特征)
    继承的主要作用在于,在已有的基础上进行功能的扩充操作
    要使用继承,必须要满足“is-a”关系,eg: Student is a Person即满足从属关系

继承使用
子类使用extends继承父类,无须重复编写代码的情况下拥有父类的所有成员。(父类->基类;子类->派生类)

4、继承的使用限制
(1)子类对象在实例化前一定会先实例化父类对象,先调用父类构造方法再调用子类构造方法.
(2)java只允许单继承不允许多继承,一个类只能继承一个父类;不允许多重继承,但可以使用多层继承
(3)在进行继承的时候,子类会继承父类所有的结构(包括私有域)
隐式继承:继承父类所有私有域
显式继承:继承父类的所有非私有域,可以直接调用

第十三章、方法覆写(override)

定义:方法覆写发生在有继承关系的类之间,子类定义了与父类相同的方法(方法名称相同、参数的个数、类型、返回值全部都相同) 被覆写的方法不能拥有比父类更为严格的访问控制权限,即子类不能降低父类的方法访问权限。

存在方法覆写时,到底调用的是哪一个类的同名方法:
a.当前使用的对象是通过哪个类new的
b.调用方法是否被当前对象所在的类覆写,一旦被覆写,一定调用被覆写后的方法。

访问权限
private(仅限本类访问) < default(包访问权限) 同一个源文件中都可以使用< public
子类权限要大于等于父类权限。
方法覆写不能出现private权限

属性覆写(了解):子类定义了与父类同名的属性

第十四章、综合案例:继承分析

1、继承性的作用
 可以实现类结构的重复利用,可以对类功能进行扩充。
2、优点
 表面上就是减少重复的代码,实际上也是,这个特别舒服,省了复制粘贴
3、缺点
 存在单继承局限性,这个就是说一个子类只能继承一个父类。还有一个缺点就是,父类不能强制性要求子类必须覆写父类中的一些方法(这个敲多代码之后就会慢慢理解)
4、设计继承的原因
 就是实现类结构的重复利用,提高代码的重用性

比如创建一个多线程的类,有两种创建的方式。

1、继承 Thread 类:缺点是该类不能再继承其他类。

2、实现Runable接口:(推荐的方式),解决 java 单继承的缺点。

第十五章、Annotation注解

public class AnnotationTest { 

    @Test
    void test() { 
        System.out.println("hahhaa");
    }
}
public enum ElementType { 
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /** * Type parameter declaration * * @since 1.8 */
    TYPE_PARAMETER,

    /** * Use of a type * * @since 1.8 */
    TYPE_USE
}

第十六章、多态性

相同的消息使得不同的类做出不同的响应。

Sun sun = new Sun();
sun.parentMethod1();   //this is a childMethod

WangFei wangFei = new Sun();
wangFei.parentMethod1();//this is a childMethod

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sb3YUxkx-1615520177502)(/home/wf/Pictures/子类与父类的关系.png)]

父类的引用指向了子类的实例,子类重写了父类的方法,则调用执行的是new对象的方法,否则执行父类的当前方法。

第十七章、object类

  1. 首先,Object类是所有类的超类,即是所有类的父类。
  2. 类中定义了equls方法和hashCode方法等。
package java.lang;


public class Object { 

    private static native void registerNatives();
    static { 
        registerNatives();
    }

    
    public final native Class<?> getClass();

    
    public native int hashCode();

    public boolean equals(Object obj) { 
        return (this == obj);
    }

   
    protected native Object clone() throws CloneNotSupportedException;

    public String toString() { 
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

  
    public final native void notify();

    public final native void notifyAll();

   
    public final native void wait(long timeout) throws InterruptedException;

    
    public final void wait(long timeout, int nanos) throws InterruptedException { 
        if (timeout < 0) { 
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) { 
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0) { 
            timeout++;
        }

        wait(timeout);
    }

   
    public final void wait() throws InterruptedException { 
        wait(0);
    }

   
    protected void finalize() throws Throwable {  }
}

第十八章、抽象类的定义和应用

抽象类定义规则:
1.抽象类和抽象方法必须用abstract关键字来修饰

2.抽象类不能直接实例化,也就是不能直接使用new关键字产生对象,其实,抽象类就是一个模板,具体实现交给子类。

public abstract class People{ }

People p = new People(); //错误,People是抽象类,无法实例化
3.抽象方法定义时,只需要声明,不需要实现

public abstract class People{ 
	public abstract void test();
}

4.含抽象方法的类必须被声明为抽象类,抽象类的子类必须实现所有的抽象方法后,才能被实例化,否则这个子类还是个抽象类.

提示:子类继承父类,也会继承下父类的访问权限为公有的方法,然后子类使用同样的方法名,而执行自己的方法体,我们称为方法的重写(override),这里我们就注意到,子类在继承抽象类后,我们来完成方法体,用的是“实现”而不是“重写”。

5、抽象类允许有普通方法,但是普通类一定不允许有抽象方法。

需要注意的是:

  • 抽象类可以存在构造方法,用来初始化抽象类的属性,
  • 抽象类不能使用final定义.

第十九章、包装类

java是面向对象语言,但是还是定义了基本数据类型。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bfyQGhJm-1615520177504)(/home/wf/Pictures/包装类结构.png)]

第20章、接口的定义与使用

public interface Wangfei { 
	public static final int wangfei = 0;
    
    public void test();
}
  1. 接口不能实例化,即使用 new 关键字产生对象。
  2. 通过关键字 implements 实现接口。
  3. 子类或者子接口必须实现父接口的所有方法。
  4. 变量必须使用 static final 修饰。
  5. 方法不能用 {} 方法体,也就意味着只能通过直接子类或者间接子类实现方法。
  6. 方法修饰符必须是 public 或者默认类型。不需要写abstract修饰,内部已经隐式添加 abstract 修饰符。
  7. 无构造方法。
  8. 支持多继承。
  9. 在设计模式中的接口隔离原则是设计模式的七大设计原则之一。接口隔离就是将功能尽可能的具有小的耦合性。
package com.wf.interfacetest;

public interface Base_interface { 

    void test1();
    
    void test2();
    
    void test3();
    
    void test4();
    
    
}
package com.wf.interfacetest;

public class Test1 implements Base_interface{ 
    @Override
    public void test1() { 
		System.out.println("this is a test1()");
    }

    @Override
    public void test2() { 

    }

    @Override
    public void test3() { 

    }

    @Override
    public void test4() { 

    }
}

类 test1 只需要 test1() 方法,但是还会实现其他没用的方法,这会造成浪费。

解决方案:定制实现类的接口,即实现类需要哪些功能就创建哪些方法。

第22章、泛型

  1. 泛型是“类型参数化”,即引用类型参数化。
  2. 泛型的参数不能是基本数据类型。因为在参数转化的过程中是将传入的参数转化为 Object 超类。基本数据类型不能转化。
  3. 泛型解决 ClassCastException 类转化异常。
  4. JDK5 提供的编译器类型安全检测机制。
  5. ? :表示不确定的 java 类型。
  6. T:表示具体的java类型。
  7. E:表示元素
  8. K,V:表示key value。比如Map<String,Object>.
  9. 上界:<? extends Object>.下界:<? super StringBuilder>。

第23章、包的定义与使用

  1. 包其实就是一个文件夹,用于区分同类。
  2. 命名规则:建议小写。
  3. 限制访问权限。
权限关键字/限制范围publicprotect(默认)private
不同包
同包
不同类
同类

Java 包的命名规则如下:

  • 包名全部由小写字母(多个单词也全部小写)。
  • 如果包名包含多个层次,每个层次用“.”分割。
  • 包名一般由倒置的域名开头,比如 com.baidu,不要有 www。
  • 自定义包不能 java 开头。

注意:如果在源文件中没有定义包,那么类、接口、枚举和注释类型文件将会被放进一个无名的包中,也称为默认包。在实际企业开发中,通常不会把类定义在默认包下。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-itJmzdqT-1615520177506)(/home/wf/Pictures/类UML.png)]

  • “+” : 表示 public 级别
  • “-”:表示 private 级别
  • “”(省略):表示包级别
  • “#”:表示 protected 级别
/** * @author wf */
// 继承/实现
public class Test2 extends Test1 implements Test3{ 

    // 关联关系
    private Test1 test1;

    // 参数
    public void method(Test1 test2) { 
        Test1 test3 = new Test1();


    }
}
class Test1{ }
interface Test3{ }

第24章、UML

第25章、单例设计模式

class MySingleton{ 
    // 懒汉式
    private final static MySingleton mySingleton = null;
    // 饿汉式
    private final static MySingleton mySingletonLasy = new MySingleton();
    
    private MySingleton(){ }
    
    public synchronized static MySingleton getInstance(){ 
        return new MySingleton();
    }
    
    public synchronized static MySingleton getInstanceLasy(){ 
        return mySingletonLasy;
    }
}

为了程序运行的高效,设计出单例模式,有些类或者资源的使用率很高,以前是每次使用都得创建对象,后来 Spring 框架给出了解决方案:IOC 容器。就是将那些常用的类或者资源在系统启动的时候进行创建。使用的时候直接使用。

  • 饿汉式:不用之前就创建资源。(建议)
public class Singleton {   
    private static Singleton instance = new Singleton();  
    private Singleton (){ }  
    public static Singleton getInstance() {   
    return instance;  
    }  
}
  • 懒汉式:只有在用的时候再使用。
  • synchronized 修饰的作用:防止多线程的环境下产生多个该对象。

使用场景:

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

第26章、枚举(enum)

  1. 先定义枚举常量,再定义方法。
  2. EnumMap
  3. EnumSet
package com.wf.enumtest;

import java.util.EnumMap;

public enum WebSite { 
    /** * 百度 */
    BAIDU,
    /** * 360 */
    com360,
    /** * 新浪 */
    XINLANG,
    /** * 私有 */
    WF;

    private EnumMap<WebSite,String> enumMap = new EnumMap<>(WebSite.class);

    public void WebSite1(){ 
        enumMap.put(WebSite.BAIDU,"http://www.baidu.com");

    }


    public String getUrl(WebSite webSite) { 
        return this.enumMap.get(webSite);
    }
}

第27章、异常的铺获及处理

Java异常机制用到的几个关键字:try、catch、finally、throw、throws。

try – 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。
catch – 用于捕获异常。catch用来捕获try语句块中发生的异常。
finally – finally语句块总是会被执行。它主要用于回收在try块里打开的物理资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
throw – 用于抛出异常。
throws – 用在方法签名中,用于声明该方法可能抛出的异常。主方法上也可以使用throws抛出。如果在主方法上使用了throws抛出,就表示在主方法里面可以不用强制性进行异常处理,如果出现了异常,就交给JVM进行默认处理,则此时会导致程序中断执行。

产生异常的原因:

  • 用户输入了非法数据。
  • 要打开的文件不存在。
  • 网络通信时连接中断,或者JVM内存溢出。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UsKtLNbx-1615520177507)(/home/wf/Pictures/异常.png)]

finally块和return

首先一个不容易理解的事实:在 try块中即便有return,break,continue等改变执行流的语句,finally也会执行。
finally中的return 会覆盖 try 或者catch中的返回值。
finally中的return或异常会抑制(消灭)前面try或者catch块中的异常。

第 28 章、内部类

内部类:将一个类嵌入其他类中。称之为内部类。

内部类的优点:

  1. 内部类与外部类可以方便的访问彼此的私有域(包括私有方法、私有属性)。
  2. 内部类是另外一种封装,对外部的其他类隐藏。
  3. 内部类可以实现java的单继承局限。

内部类的缺点:

结构复杂。

内部类可以独立地继承一个抽象类或者实现一个接口,无论外部类是否也这样做了,对内部类都没有影响

内部类出现的位置

1、成员变量位置

package com.wf.innerclass;

public class Outer { 
    class Inner{ 

    }
}

2、局部位置

package com.wf.innerclass;

public class Outer { 
// class Inner{ 
//
// }
    
    
    public void method() { 
        class Method_class{ 
            
        }
    }
}

3、静态内部类

package com.wf.innerclass;

public class Outer { 

    static class Inner{ 
        
    }
}
// 静态内部类无法访问外部类的成员

Outer.Inner inner = new Outer.Inner;访问

4、匿名内部类(使用最多)

特别注意:
在使用匿名内部类时,要记住以下几个原则。
1.匿名内部类不能有构造方法。
2.匿名内部类不能定义任何静态成员,方法和类。
3.匿名内部类不能使用public,protected,private,static。
4.只能创建匿名内部类的一个实例。
5.一个匿名内部类一定时在 new 后面,用其隐含实现一个接口或实现一个类。
6.因匿名内部类为局部内部类,所以,局部内部类的所有限制都对其有效。
7.内部类只能访问外部类的静态变量或静态方法。
8.内部类当中的 this 指的是匿名内部类本身,如果使用外部类中的 this,则“外部类.this”。

第 29 章、函数式编程

函数式接口:有且仅有一个函数的接口。

package com.wf.jdk8;

public interface Inter { 
    public void printString();
}

class Show{ 
    
    public static void main(String[] args) { 
        // before JDK8
        Inter inter = new Inter() { 
            @Override
            public void printString() { 
                System.out.println("哈哈");
            }
        };
        
        // after JDK8
        Inter jdk8 = () -> { 
            System.out.println("你好");  
        };
    }
    
}

@FunctionalInterface :注解只是为了表明这是一个函数式接口,函数式接口只能包含一个方法。

@FunctionalInterface
public interface Test{ 
    boolean method();
}

只能够访问局部对应的外部区域的局部final变量,以及成员变量和静态变量。

但不能修改Lambda域外的局部非final变量

无法访问接口默认(default)方法

第 30 章、链表的定义与使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AHHo8y7L-1615520177509)(/home/wf/Pictures/链表.png)]

  • 从上面的总结我们可以看出,ArrayList和Vector底层采用的都是数组数据结构,而LinkedList采用的链表的数据结构.
  • 对于插入一个元素到指定的位置,由于ArrayList和Vector采用的是数组的形式,所以需要先将原先的元素进行复制,然后再插入。而LinkedList直接通过改变要插入的节点的指针即可。所以插入元素时,LinkedList比ArrayList和Vector的要快。
  • 对于删除指定位置的元素和插入元素类似,ArrayList和Vector需要进行一次复制然后执行删除,所以没有LinkedList执行的速度快(其实这里是有一点问题的就是我们要删除一个LinkedList中的元素需要先将进行一次查找,然后进行删除,时间复杂度都是O(n)).
  • 对于随机访问,ArrayList和Vector采用数组结构可以根据数组索引进行定位,因此能够快速的访问,而LinkedList最坏的情况可能需要O(n)的时间。
  • 对于Vector因为底层实现的方法都是采用了synchronized方法,所以是线程安全的,而ArrayList和LinkedList则是线程不安全的
  • 对于ArrayList和Vector如果我们不指定初始容量,那么初始化的容量为10,LinkedList初始化为null.
    ArrayList 和Vector的需要扩容机制而LinkedList不需要,ArrayList在添加元素的时候,会判断需要是否需要扩容,如果需要则扩容为之前的1.5倍,而Vector则是扩容为之前的2倍。

Set和List的区别

    1. Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
    1. Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>
    1. List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector>

第 31 章、List 集合

  1. List接口继承自顶层容器 Collection 接口。

  2. list 代表列表的意思。

  3. 常用的列表是 ArrayList、LinkedList。

  4. ArrayList 底层使用数组和链表实现数据的存储,内容是无序,可能重复的。特点是检索速度快,因为数据在内存中是连续的,即物理上是连续存储。

  5. ArrayList源码解析

    总结
    (01) ArrayList 实际上是通过一个数组去保存数据的。当我们构造ArrayList时;若使用默认构造函数,则ArrayList的默认容量大小是10
    (02) 当ArrayList容量不足以容纳全部元素时,ArrayList会重新设置容量:新的容量=“(原始容量x3)/2 + 1”
    (03) ArrayList的克隆函数,即是将全部元素克隆到一个数组中。
    (04) ArrayList实现java.io.Serializable的方式。当写入到输出流时,先写入“容量”,再依次写入“每一个元素”;当读出输入流时,先读取“容量”,再依次读取“每一个元素”。

  6. LinkedList

第 32 章、Set 集合

第 33 章、集合输出

for

foreach

Iterator

第 34 章、map集合

Map<K,V> hashMap = new HashMap<>();

  1. HashMap:这也是我们平时开发中最常用的map,底层实现为数组+链表,它根据键key的HashCode值存储数据,可以使用get(key)来获取键对应的值,是线程不安全的。HashMap允许存在一条键为null的记录。在数据量小的时候,HashMap是以链表的模式存储数据;当数据量变大后,为了进行快速查找,会将这个链表变为红黑树来进行保存,使用key的哈希值来进行查找。

  2. TreeMap:该map将存储的键值对进行默认排序,并且还能够指定排序的比较器,是线程不安全的。TreeMap不允许键值为null。

  3. Hashtable:与HashMap类似,不同的是,Hashtable是线程安全的,在进行插入是会比HashMap慢,并且key和value的值均不允许为null。对个线程同时访问Hashtable对象时,第一个线程获取锁后,会引发其他线程进行等待,知道第一个线程释放掉锁。

  4. LinkedHashMap:该map保证了对面在插入值得顺序,在查询遍历的时候会比HashMap慢,是线程不安全的。允许key和value均为空。

  5. ConcurrentHashMap:该map对象时线程安全的,与Hashtable不同的是,ConcurrentHashMap采用了分段锁技术,没有同Hashtable一样锁住全部数据,而是锁定线程访问的那一段数据。对个线程在访问不同段数据时就不会存在等待。

  6. ConcurrentHashMap的主干是Segment数组。没有Segment就相当于一个小的HashTable,知道不修改访问同一个Segment上的数据就不会存在并发问题。

  7. Segment是一种可重入锁,继承ReentranLock类。下面简单介绍一下ReentranLock与synchronized的区别:

    • Synchronized是一个同步锁。当一个线程A访问synchronized修饰的代码块时,线程A就会获取该代码块的锁,如果这时存在其他线程范围该代码块时,将会阻塞,但是不影响这些线程访问其他非同步代码块。
    • ReentranLock是可重入锁。由构造方法可知,该锁支持两种锁模式,公平锁和非公平锁。默认是非公平的。
  8. 公平锁:当线程A获取访问该对象,获取到锁后,此时内部存在一个计数器num+1,其他线程想访问该对象,就会进行排队等待(等待队列最前一个线程处于待唤醒状态),直到线程A释放锁(num = 0),此时会唤醒处于待唤醒状态的线程进行获取锁的操作,一直循环。如果线程A再次尝试获取该对象锁是,会检查该对象锁释放已经被占用,如果被占用,会做一次是否为当前线程占用锁的判断,如果是内部计数器num+1,并且不需要进入等待队列,而是直接回去当前锁。

  9. 非公平锁:当线程A在释放锁后,等待对象的线程会进行资源竞争,竞争成功的线程将获取该锁,其他线程继续睡眠。

  10. 公平锁是严格的以FIFO的方式进行锁的竞争,但是非公平锁是无序的锁竞争,刚释放锁的线程很大程度上能比较快的获取到锁,队列中的线程只能等待,所以非公平锁可能会有“饥饿”的问题。但是重复的锁获取能减小线程之间的切换,而公平锁则是严格的线程切换,这样对操作系统的影响是比较大的,所以非公平锁的吞吐量是大于公平锁的,这也是为什么JDK将非公平锁作为默认的实现。

    对于Map的遍历,建议使用entrySet迭代器方式,在进行大量级数据时,效率会高很多。

第 35 章、集合工具类

https://doc.bccnsoft.com/docs/jdk8u12-docs/api/

第 36 章、Stream 数据流

https://doc.bccnsoft.com/docs/jdk8u12-docs/api/

    原文作者:小飞LOVE霞
    原文地址: https://blog.csdn.net/qq_37950196/article/details/114692080
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞