Java语法快速学习-黑马程序员(个人整理版本)

Java入门基础视频教程,java零基础自学首选黑马程序员Java入门教程(含Java项目和Java真题)_哔哩哔哩_bilibili为了帮助广大对Java有兴趣和立志进入本行业的零基础学员,本套课程由此而生,舍弃了冗长的理论,结合软件公司一个个真实的应用需求,来加强大家对知识的理解和掌握。本课程知识全面透彻,案例极为丰富,阶段课程完结后都配备了综合实战案例,具备大量优雅、高质量的代码供初学者训练,手把手边学边干,清楚,实用!是Java零基础学员极好的入门视频。课程从Java语言的简介到程序开发执行的原理、集成开发工具IDEA的https://www.bilibili.com/video/BV1Cv411372m?p=128

本文为P1-P127,之后的内容由于项目暂时用不上,所以没学

Java层次

Java语法快速学习-黑马程序员(个人整理版本)_第1张图片

基础格式

package com.itheima.test;    //包名:一般为公司网址倒写

public class Test {    //类名:Test
}

main函数

main加tab键

package com.itheima.test;

public class Test {
    public static void main(String[] args) {

    }
}

输出语句

System.out.println();
package com.itheima.test;

public class Test {
    public static void main(String[] args) {
        System.out.println("HelloWorld");
    }
}

注释

 单行注释

//单行注释
package com.itheima.note;

public class NoteDemo {
    public static void main(String[] args) {
        //单行注释
    }
}

多行注释

/*
    注释内容1
    注释内容2
*/
package com.itheima.note;

public class NoteDemo {
    public static void main(String[] args) {
        /*
            注释内容1
            注释内容2
        */
    }
}

文档注释:文档注释的内容是可以提取到一个程序说明文档中去的

/**
    文档注释
*/
package com.itheima.note;
/**
    文档注释
*/

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

Java语法快速学习-黑马程序员(个人整理版本)_第2张图片

变量

int a=10;
double b=2.0;
float c=3.0;

输入

import java.util.Scanner;
        Scanner sc=new Scanner(System.in);
        int age =sc.nextInt();
        String name =sc.next();
package com.itheima.scanner;

import java.util.Scanner;

// 1、导包操作〔并不需要自己写的,以后通过工具进行导入更方使)
public class ScannerDemo {
    public static void main(String[] args) {
        //2.得到一个键盘扫描对象
        Scanner sc=new Scanner(System.in);
        //3.调用sc对象的功能等待用户输入的数据
        //这个代码会等待用户输入数据,直到用户输入完数据并按了回车键就会把数据拿到
        System.out.println("请输入你的年龄:");
        int age =sc.nextInt();
        System.out.println("您的年龄是:"+age);

        System.out.println("请输入你的名称:");
        String name =sc.next();
        System.out.println("欢迎:"+name);
    }
}

if

if (条件表达式) {

    语句体; 

}
if (条件表达式) {
    语句体1;	
} else {
    语句体2;	
}
if (条件表达式1) {
    语句体1;	
} else if (条件表达式2) {
    语句体2;	
} else if (条件表达式3) {
    语句体3;	
} 
. . .
else {
    语句体n+1;
}

switch

switch(表达式){
    case 值1:
        执行代码1;
        break;
    case 值2:
        执行代码2;
        break;
    ...
    default:
        执行代码n;
        //break;

for循环

for (初始化语句; 循环条件; 迭代语句)  {	循环体语句(重复执行的代码);
}
// 输出3次HelloWorld
for (int i = 0; i < 3; i++) {   
    System.out.println("Hello World");
}

while循环

初始化语句;
while (循环条件) {
    循环体语句(被重复执行的代码);
    迭代语句;
}
int i = 0;
while (i < 3) {
    System.out.println("Hello World");
    i++;
}

do-while循环

初始化语句;
do {
    循环体语句;
    迭代语句;
} while (循环条件);
int i = 0;
do {
       System.out.println(“Hello World!");
       i++;
} while( i < 3);

死循环

for(;;){
}
while(true){
}
do{
}while(true);

Random随机数

import java.util.Random;
        Random r = new Random();
        int data = r.nextInt(10); // 0 - 9 不包含10的(包前不包后)
package com.itheima.random;

import java.util.Random;

public class RandomDemo1 {
    public static void main(String[] args) {
        // 目标:学会使用Java提供的随机数类Random
        // 1、导包
        // 2、创建随机数对象
        Random r = new Random();

        // 3、调用nextInt功能(方法)可以返回一个整型的随机数给你
        for (int i = 0; i < 20; i++) {
            int data = r.nextInt(10); // 0 - 9 不包含10的(包前不包后)
            System.out.println(data);
        }

        System.out.println("-----------------------");
        // 1 - 10 ==> -1 ==> (0 - 9) + 1
        int data = r.nextInt(10) + 1;
        System.out.println(data);

        // 3 - 17 ==> -3 ==> (0 - 14) + 3
        int data1 = r.nextInt(15) + 3;
        System.out.println(data1);
    }
}

数组

// 完整格式
数据类型[]  数组名 = new 数据类型[]{元素1,元素2 ,元素3… };
double[] scores = new double[]{89.9, 99.5, 59.5, 88.0};
int[] ages = new int[]{12, 24, 36}
// 简化格式
数据类型[] 数组名 = { 元素1,元素2 ,元素3,… };
int[] ages = {12, 24, 36};

数据类型[] 数组名”也可以写成 “数据类型 数组名[] 

int[] ages =...;  
int ages[] =...;  

double[] scores = ...;
double scores[] = ...;

数组的访问

// 取值
System.out.println(arr[0]); // 12
// 赋值
arr[2] = 100;
System.out.println(arr[2]); // 100

数组的长度属性:length

// 获取数组的长度(就是数组元素的个数)
System.out.println(arr.length); // 3

数组的动态初始化

数据类型[]  数组名 = new 数据类型[长度];
int[] arr = new int[3];//新建三个整形空间

方法(函数)

修饰符  返回值类型  方法名( 形参列表 ){
         方法体代码(需要执行的功能代码)
         return 返回值;
}
public static int add(int a,int b){
    int c=a+b;
    return c;
}

方法的调用格式

//方法名(…); 
int sum = add(10, 20);
System.out.println(sum);

方法重载

public class Test {
    //(1)默认发一枚武器
    public static void fire(){
            System.out.println(“默认发射一枚武器给米国!");
    }

    //(2)可以指定地区发射一枚武器。
    public static void fire(String location){
        System.out.println("给"+location+"发射一枚武器!");
    }

    //(3)可以指定地区发射多枚武器。
    public static void fire(String location , int nums){
        System.out.println("给"+location+"发射"+nums+"枚武器!");
    }
}

fire();
fire("米国");
fire("岛国" , 1000);

面向对象编程

定义类,才能获得对象

public class 类名{
    1、成员变量(代表属性)
    2、成员方法(代表行为)
    3、构造器(后面学习)
    4、代码块(后面学习)
    5、内部类(后面学习)
}
public class Car{
    String name;
    double price;
    
    public void start(){
        system.out.println(name+"启动了! ");
    }
    public void run(){
        system.out.println("售价为:" + price +"的" +name+"跑的快! ");
    }
}

得到类的对象

//类名对象名= new类名();
Car c2 = new Car();

使用对象

对象.成员变量;对象.成员方法(...)

car.name;
car.price;
car.start();

构造器

public class Car {
    //无参数构造器(默认存在的)
}
public class Car {
    //无参数构造器(需要写出来了)
    public Car(){
    }
    //有参数构浩
    public car(String n,String b){
    }
}

this关键字:当前对象的地址

public class car {
    String name;
    double price;
    public car(string name , double price){
    this.name = name;
    this.price = price;
    }
}
public class car {
    String name;
    double price;
    public void gowith(String name){
    system.out.println(this.name +"正在和"+name +"一起比赛!!");
    }
}

封装:隐藏实现细节,暴露出合适的访问方式。(合理隐藏、合理暴露)

public class Student {
    private int age;
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age >= 0 && age <= 200) {
            this.age = age;
        }else {
            System.out.println("请检查年龄数值");
        }
    }
}

String字符串创建

String s1 = "abc" ;
String s2 = "abc" ;
System.out.println(s1 == s2); //true


char[] chs = {'a', 'b', 'c'};
string s3 = new String(chs);
String s4 = new String(chs);
System.out.println(s3 == s4); //false

字符串的内容比较

推荐使用String类提供的“equals”比较:只关心内容一样即可

public boolean equals (Object anobject)

将此字符串与指定对象进行比较。只关心字符内容是否一致!

public boolean equalsIgnorecase (string anotherString)

将此字符串与指定对象进行比较,忽略大小写比较字符串。只关心字符内容是否一致!

if(okName.equals(name ) && okPassword.equals(password)){
    System.out.println("登录成功!");
}else {
    System.out.println("用户名或者密码错误了!");
}

ArrayList集合

Java语法快速学习-黑马程序员(个人整理版本)_第3张图片

package com.itheima.arraylist;

import java.util.ArrayList;

/**
      目标: 创建ArrayList对象,代表集合容器,往里面添加元素。
 */
public class ArrayListDemo1 {
    public static void main(String[] args) {
        // 1、创建ArrayList集合的对象
        ArrayList list = new ArrayList();

        // 2、添加数据
        list.add("Java");
        list.add("Java");
        list.add("MySQL");
        list.add("黑马");
        list.add(23);
        list.add(23.5);
        list.add(false);
        System.out.println(list.add('中'));
        System.out.println(list);

        // 3、给指定索引位置插入元素
        list.add(1, "赵敏");
        System.out.println(list);
    }
}

true
[Java, Java, MySQL, 黑马, 23, 23.5, false, 中]
[Java, 赵敏, Java, MySQL, 黑马, 23, 23.5, false, 中]

ArrayList泛型

//使用泛型:<数据类型>
ArrayList list1 = new ArrayList();//此集合只能操作字符串类型的元素

ArrayList集合常用方法

Java语法快速学习-黑马程序员(个人整理版本)_第4张图片

package com.itheima.arraylist;

import java.util.ArrayList;

/**
    目标:掌握ArrayList集合的常用API
 */
public class ArrayListDemo3 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();
        list.add("Java");
        list.add("Java");
        list.add("MySQL");
        list.add("MyBatis");
        list.add("HTML");

        // 1、public E get(int index):获取某个索引位置处的元素值
        String e = list.get(3);
        System.out.println(e);

        // 2、public int size():获取集合的大小(元素个数)
        System.out.println(list.size());

        // 3、完成集合的遍历
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        // 4、public E remove(int index):删除某个索引位置处的元素值,并返回被删除的元素值
        System.out.println(list); // [Java, Java, MySQL, MyBatis, HTML]
        String e2 = list.remove(2);
        System.out.println(e2);
        System.out.println(list);

        // 5、public boolean remove(Object o):直接删除元素值,删除成功返回true,删除失败返回false
        System.out.println(list.remove("MyBatis"));
        System.out.println(list);

        ArrayList list1 = new ArrayList<>();
        list1.add("Java");
        list1.add("王宝强");
        list1.add("Java");
        list1.add("MySQL");
        System.out.println(list1);
        // 只会删除第一次出现的这个元素值,后面的不删除
        System.out.println(list1.remove("Java"));
        System.out.println(list1);


        // 6、public E set(int index,E element):修改某个索引位置处的元素值。
        String e3 = list1.set(0 , "贾乃亮");
        System.out.println(e3);
        System.out.println(list1);


    }
}

MyBatis
5
Java
Java
MySQL
MyBatis
HTML
[Java, Java, MySQL, MyBatis, HTML]
MySQL
[Java, Java, MyBatis, HTML]
true
[Java, Java, HTML]
[Java, 王宝强, Java, MySQL]
true
[王宝强, Java, MySQL]
王宝强
[贾乃亮, Java, MySQL]

static静态

static可以修饰成员变量和成员方法。

成员变量

static修饰成员变量表示该成员变量只在内存中只存储一份,可以被共享访问、修改。

public class User {
    // 成员变量
    public static int onlineNumber= 161;
    
    private String name;
    private int age;
    …
}

推荐访问方式:类名.静态成员变量

User.onlineNumber

成员方法

静态成员方法(有static修饰,属于类),建议用类名访问,也可以用对象访问。

实例成员方法(无static修饰,属于对象),只能用对象触发访问。

package com.itheima.d2_static_method;

public class Student {
    private String name;
    private int age;

    /**
        实例方法:无static修饰,属于对象的,通常表示对象自己的行为,可以访问对象的成员变量
     */
    public void study(){
        System.out.println(name + "在好好学习,天天向上~~");
    }

    /**
        静态方法:有static修饰,属于类,可以被类和对象共享访问。
     */
    public static void getMax(int a, int b){
        System.out.println(a > b ? a : b);
    }

    public static void main(String[] args) {
        // 1、类名.静态方法
        Student.getMax(10, 100);
        // 注意:同一个类中访问静态成员 可以省略类名不写
        getMax(200, 20);

        // 2、对象.实例方法
        // study(); // 报错的
        Student s = new Student();
        s.name = "全蛋儿";
        s.study();

        // 3、对象.静态方法(不推荐)
        s.getMax(300,20);
    }
}

饿汉单例设计模式

在用类获取对象的时候,对象已经提前为你创建好了

设计步骤:

定义一个类,把构造器私有

定义一个静态变量存储一个对象

/** a、定义一个单例类 */
public class SingleInstance {
    /** c.定义一个静态变量存储一个对象即可 :属于类,与类一起加载一次 */
    public static SingleInstance instance = new SingleInstance ();

    /** b.单例必须私有构造器*/
    private SingleInstance (){
        System.out.println("创建了一个对象");
    }
}

懒汉单例设计模式

在真正需要该对象的时候,才去创建一个对象(延迟加载对象)。

设计步骤:

定义一个类,把构造器私有

定义一个静态变量存储一个对象。

提供一个返回单例对象的方法

/** 定义一个单例类 */
class SingleInstance{
    /** 定义一个静态变量存储一个对象即可 :属于类,与类一起加载一次 */
    public static SingleInstance instance ; // null

    /** 单例必须私有构造器*/
    private SingleInstance(){}

    /** 必须提供一个方法返回一个单例对象  */
    public static SingleInstance getInstance(){
        ...
       return ...;
    }
}

继承

Java中提供一个关键字extends,用这个关键字,我们可以让一个类和另一个类建立起父子关系。

Student称为子类(派生类),People称为父类(基类 或超类)

public class Student extends People {}

①子类可以继承父类的属性和行为,但是子类不能继承父类的构造器。

②Java是单继承模式:一个类只能继承一个直接父类。

③Java不支持多继承、但是支持多层继承。

④Java中所有的类都是Object类的子类。

父类文件People.java

package com.itheima.d7_extends;

public class People {
    private String name;
    private int age;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

子类文件Student.java继承

package com.itheima.d7_extends;

public class Student extends People{
    /**
       独有的行为
     */
    public void study(){
        System.out.println(getName() + "学生开始学习~~~~~");
    }
}

测试

package com.itheima.d7_extends;

public class Test {
    public static void main(String[] args) {
        // 创建子类对象,看是否可以使用父类的属性和行为
        Student s = new Student();
        s.setName("西门"); // 父类的
        s.setAge(25);// 父类的
        System.out.println(s.getName());// 父类的
        System.out.println(s.getAge());// 父类的
        s.study();
    }
}

西门
25
西门学生开始学习~~~~~

super关键字:指定访问父类的成员

关键字

访问成员变量

访问成员方法

访问构造方法

this

this.成员变量

访问本类成员变量

this.成员方法(…)

访问本类成员方法

this(…)

访问本类构器

super

super.成员变量

访问父类成员变量

super.成员方法(…)

访问父类成员方法

super(…)

访问父类构造器

    public Student(String name, int age, String className) {
        super(name, age);
        this.className = className;
    }

this()访问本类构造器

后台创建对象封装数据的时候如果用户没有输入学校,则默认使用“黑马培训中心”。如果用户输入了学校则使用用户输入的学校信息

public class Student {        
    private String schoolName;
    private String name;
   
    public Student(String name){
          this(name , “黑马培训中心”);	
    }	
     
    public Student(String name , String schoolName ){
          this.name = name;
          this.schoolName = schoolName;
    }	
}

包是用来分门别类的管理各种不同类的,类似于文件夹、建包利于程序的管理和维护

建包的语法格式:package 公司域名倒写.技术名称。报名建议全部英文小写,且具备意义

建包语句必须在第一行,一般IDEA工具会帮助创建

package com.itheima.javabean;
public class Student {
       
}

导包 

相同包下的类可以直接访问不同包下的类必须导包,才可以使用!导包格式:import 包名.类名;

假如一个类中需要用到不同类,而这个两个类的名称是一样的,那么默认只能导入一个类,另一个类要带包名访问

Java语法快速学习-黑马程序员(个人整理版本)_第5张图片

package com.itheima.d1_package;


import com.itheima.d1_package.demo1.Animal;
import com.itheima.d1_package.demo1.Cat;

public class Test {
    public static void main(String[] args) {
        // 导包:相同包下的类可以直接访问。
        Student s = new Student();

        // 不同包下的类必须导包才可以使用
        Animal a = new Animal();

        // 使用默认导包的类:demo1下的cat
        Cat c1 = new Cat();
        c1.run();

        // 指定使用demo2下的Cat类
        com.itheima.d1_package.demo2.Cat c2 = new  com.itheima.d1_package.demo2.Cat();
        c2.run();
    }
}

权限修饰符

权限修饰符:是用来控制一个成员能够被访问的范围的

自己定义成员(方法,成员变量,构造器等)一般满足如下要求:

  1. 成员变量一般私有。
  2. 方法一般公开。
  3. 如果该成员只希望本类访问,使用private修饰。
  4. 如果该成员只希望本类,同一个包下的其他类和子类访问,使用protected修饰

修饰符

同一 个类中

同一个包中

其他类

不同包下的

子类

不同包下的

无关类

private

缺省

protected

public

package com.itheima.d2_modifier.itcast;

public class Fu {
    // 1.private 只能本类中访问
    private void show1() {
        System.out.println("private");
    }

    // 2.缺省:本类,同一个包下的类中。
    void show2() {
        System.out.println("缺省");
    }

    // 3.protected:本类,同一个包下的类中,其他包下的子类
    protected void show3() {
        System.out.println("protected");
    }

    // 4.任何地方都可以
    public void show4() {
        System.out.println("public");
    }

    public static void main(String[] args) {
        //创建Fu的对象,测试看有哪些方法可以使用
        Fu f = new Fu();
        f.show1();
        f.show2();
        f.show3();
        f.show4();
    }
}

private
缺省
protected
public

final最终

final 关键字是最终的意思,可以修饰(方法,变量,类)

修饰方法:表明该方法是最终方法,不能被重写。

class Animal{
    public final void run(){
        System.out.println("动物可以跑~~");
    }
}

class Tiger extends Animal{
//    @Override
//    public void run() {
//        System.out.println("老虎跑的贼快~~~");
//    }
}

修饰变量:表示该变量第一次赋值后,不能再次被赋值(有且仅能被赋值一次)。

变量有几种:
   局部变量。
   成员变量。
        -- 1、静态成员变量。
        -- 2、实例成员变量。final基本上不会用来修饰实例成员变量,没有意义!
public static void main(String[] args) {
       // final修饰变量,变量有且仅能被赋值一次。
        final int age;
        age = 12;
        // age = 20; // 第二次赋值,报错了!
}

修饰类:表明该类是最终类,不能被继承。

final class Animal{
}
class Cat extends Animal{    //报错,不能继承final修饰的类
}

final修饰变量的注意

final修饰的变量是基本类型:那么变量存储的数据值不能发生改变。

final修饰的变量是引用类型:那么变量存储的地址值不能发生改变,但是地址指向的对象内容是可以发生变化的。

package com.itheima.d3_final;

public class Test2 {
    public static void main(String[] args) {
        // final修饰变量的注意事项:
        // 1、final修饰基本类型变量,其数据不能再改变
        final double rate = 3.14;
        // rate = 3.15; // 第二次赋值,报错

        // 2、final修饰引用数据类型的变量,变量中存储的地址不能被改变,但是地址指向的对象内容可以改变。
        final int[] arr = {10, 20, 30};
        System.out.println(arr);
        // arr = null; // 属于第二次赋值,arr中的地址不能被改变
        arr[1] = 200;
        System.out.println(arr);
        System.out.println(arr[1]);
    }
}

常量

常量是使用了public static final修饰的成员变量,必须有初始化值,而且执行的过程中其值不能被改变。

常量的作用和好处:可以用于做系统的配置信息,方便程序的维护,同时也能提高可读性。

常量命名规范:英文单词全部大写,多个单词下划线连接起来。

public class Constant {
    public static final String SCHOOL_NAME  = “传智教育";
    public static final String LOGIN_NAME  = “admin";
    public static final String PASS_WORD  = “123456";
} 

枚举

 修饰符 enum 枚举名称{
            第一行都是罗列枚举类实例的名称。
}
枚举的第一行必须罗列枚举类的对象名称,建议全部大写
public enum Season{
    SPRING , SUMMER , AUTUMN , WINTER;
}
做信息标志和分类
public enum Orientation {
    UP, DOWN, LEFT, RIGHT;
}

案例 :现在开发的超级玛丽游戏需要接收用户输入的四个方向的信号(上下左右),以便控制玛丽移动的方向

package com.itheima.d5_enum;

import javax.swing.*;
import java.awt.event.ActionEvent;

/**
    目标: 常量的其他作用,做信息标志和信息分类(其实也是一种配置形式)
 */
public class EnumDemo2 {
    public static void main(String[] args) {
        // 1、创建一个窗口对象(桌子)
        JFrame win = new JFrame();
        // 2、创建一个面板对象(桌布)
        JPanel panel = new JPanel();
        // 3、把桌布垫在桌子上
        win.add(panel);
        // 4、创建四个按钮对象
        JButton btn1 = new JButton("上");
        JButton btn2 = new JButton("下");
        JButton btn3 = new JButton("左");
        JButton btn4 = new JButton("右");
        // 5、把按钮对象添加到桌布上去
        panel.add(btn1);
        panel.add(btn2);
        panel.add(btn3);
        panel.add(btn4);
        // 6、显示窗口
        win.setLocationRelativeTo(null);
        win.setSize(300,400);
        win.setVisible(true);


        btn1.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                move(Orientation.UP) ; // 让玛丽往上跳
            }
        });
        btn2.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                move(Orientation.DOWN) ; // 让玛丽往下跳
            }
        });
        btn3.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                move(Orientation.LEFT) ; // 让玛丽往左跑
            }
        });
        btn4.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                move(Orientation.RIGHT) ; // 让玛丽往右跑
            }
        });
    }

    public static void move(Orientation o){
        // 控制玛丽移动
        switch (o) {
            case UP:
                System.out.println("玛丽往上飞了一下~~");
                break;
            case DOWN:
                System.out.println("玛丽往下蹲一下~~");
                break;
            case LEFT:
                System.out.println("玛丽往左跑~~");
                break;
            case RIGHT:
                System.out.println("玛丽往→跑~~");
                break;
        }
    }
}

抽象类

一个类中的某个方法的具体实现不能确定

修饰符 abstract class 类名{  }
修饰符 abstract 返回值类型 方法名称(形参列表);
public abstract class Animal{
    public abstract void run();
}

接口interface

接口用关键字interface来定义,接口不能创建对象

public interface 接口名 {
       // 常量
       // 抽象方法
} 
public interface SportManInterface {
    // 接口中的成员:JDK 1.8之前只有常量 和 抽象方法
    // public static final 可以省略不写,接口默认会为你加上!
    // public static final String SCHOOL_NAME = "黑马";
    String SCHOOL_NAME = "黑马";

    // 2、抽象方法
    //  public abstract 可以省略不写,接口默认会为你加上!
    // public abstract void run();
    void run();

    // public abstract void eat();
    void eat();
}

接口类实现implements

接口是用来被类实现(implements)的,实现接口的类称为实现类。实现类可以理解成所谓的子类

修饰符 class 实现类 implements 接口1, 接口2, 接口3 , ... {
}
public interface Law {
    void rule(); // 遵章守法
}

public interface SportMan {
    void run();
    void competition();
}

/**
   实现类(子类)
 */
public class PingPongMan implements SportMan , Law{
    private String name;
    public PingPongMan(String name) {
        this.name = name;
    }

    @Override
    public void rule() {
        System.out.println(name + "要遵章守法,不能随意外出,酗酒,约会~~~");
    }

    @Override
    public void run() {
        System.out.println(name + "必须要跑步训练~~");
    }

    @Override
    public void competition() {
        System.out.println(name + "需要参加国际比赛~~");
    }
}

public class Test {
    public static void main(String[] args) {
        PingPongMan p = new PingPongMan("张继科");
        p.rule();
        p.run();
        p.competition();
    }
}

张继科要遵章守法,不能随意外出,酗酒,约会~~~
张继科必须要跑步训练~~
张继科需要参加国际比赛~~

接口:JDK8开始后新增方法

默认方法:default修饰,实现类对象调用。

静态方法:static修饰,必须用当前接口名调用

私有方法:private修饰,jdk9开始才有的,只能在接口内部被调用。

他们都会默认被public修饰。

package com.itheima.d13_interface_jdk8;

public interface SportManInter {
    /**
       1、JDK 8开始 :默认方法(实例方法)
       -- 必须default修饰,默认用public修饰
       -- 默认方法,接口不能创建对象,这个方法只能过继给了实现类,由实现类的对象调用。
     */
    default void run(){
        go();
        System.out.println("跑的很快~~~");
    }

    /**
      2、静态方法
        必须使用static修饰,默认用public修饰
        -- 接口的静态方法,必须接口名自己调用。
     */
    static void inAddr(){
        System.out.println("我们都在学习Java新增方法的语法,它是Java源码自己会用到的~~~");
    }

    /**
       3、私有方法(实例方法)
         -- JDK 1.9开始才支持的。
         -- 必须在接口内部才能被访问
     */
    private void go(){
        System.out.println("开始跑~~~");
    }

}

class PingPongMan implements SportManInter{
}

class Test{
    public static void main(String[] args) {
        PingPongMan p = new PingPongMan();
        p.run();


        SportManInter.inAddr();
        // PingPongMan.inAddr();
    }
}

开始跑~~~
跑的很快~~~
我们都在学习Java新增方法的语法,它是Java源码自己会用到的~~~

多态

同类型的对象,执行同一个行为,会表现出不同的行为

多态中成员访问特点:

特征方法调用:编译看左边,运行看右边。

变量调用:编译看左边,运行也看左边

多态的前提有继承/实现关系;有父类引用指向子类对象;有方法重写。

多态的常见形式

父类类型 对象名称 = new 子类构造器;
接口     对象名称 = new 实现类构造器;
/**
    父类
 */
public class Animal {
    public String name = "动物名称";
    public void run(){
        System.out.println("动物可以跑~~");
    }
}

public class Dog extends Animal{
    public String name = "狗名称";
    @Override
    public void run() {
        System.out.println("跑的贼溜~~~~~");
    }
}

public class Tortoise extends Animal{
    public String name = "乌龟名称";

    @Override
    public void run() {
        System.out.println("跑的非常慢~~~");
    }
}


public class Test {
    public static void main(String[] args) {
        // 目标:先认识多态的形式
        // 父类  对象名称 = new 子类构造器();
        Animal a = new Dog();
        a.run(); // 方法调用:编译看左,运行看右
        System.out.println(a.name); // 变量调用:编译看左,运行也看左,动物名称

        Animal a1 = new Tortoise();
        a1.run();
        System.out.println(a1.name); // 动物名称
    }
}

跑的贼溜~~~~~
动物名称
跑的非常慢~~~
动物名称

多态形式下的类中转换机制

1.引用数据类型的类型转换,有几种方式?

  •  自动类型转换、强制类型转换。

2.强制类型转换能解决什么问题?强制类型转换需要注意什么。

  •  可以转换成真正的子类类型,从而调用子类独有功能。
  •  有继承关系/实现的2个类型就可以进行强制转换,编译无问题。
  •  运行时,如果发现强制转换后的类型不是对象真实类型则报错。
  •  类型转换异常:ClassCastException
/**
    父类
 */
public class Animal {
    public String name = "动物名称";
    public void run(){
        System.out.println("动物可以跑~~");
    }
}

public class Dog extends Animal {
    public String name = "狗名称";
    @Override
    public void run() {
        System.out.println("跑的贼溜~~~~~");
    }

    /**
      独有功能
     */
    public void lookDoor(){
        System.out.println("在看!!!");
    }
}

public class Tortoise extends Animal {
    public String name = "乌龟名称";

    @Override
    public void run() {
        System.out.println("跑的非常慢~~~");
    }

    /**
     独有功能
     */
    public void layEggs(){
        System.out.println("在下蛋~~~");
    }
}

/**
     目标:学习多态形式下的类中转换机制。
 */
public class Test {
    public static void main(String[] args) {
        // 自动类型转换
        Animal a = new Dog();
        a.run();
//        a.lookDoor(); // 多态下无法调用子类独有功能

        // 强制类型转换:可以实现调用子类独有功能的
        Dog d = (Dog) a;
        d.lookDoor();

        // 注意:多态下直接强制类型转换,可能出现类型转换异常
        // 规定:有继承或者实现关系的2个类型就可以强制类型转换,运行时可能出现问题。
        // Tortoise t1 = (Tortoise) a;
        // 建议强制转换前,先判断变量指向对象的真实类型,再强制类型转换。
        if(a instanceof Tortoise){
            Tortoise t = (Tortoise) a;
            t.layEggs();
        }else if(a instanceof Dog){
            Dog d1 = (Dog) a;
            d1.lookDoor();
        }

        System.out.println("---------------------");
        Animal a1 = new Dog();
        go(a1);
    }

    public static void go(Animal a){
        System.out.println("预备~~~");
        a.run();
        // 独有功能
        if(a instanceof Tortoise){
            Tortoise t = (Tortoise) a;
            t.layEggs();
        }else if(a instanceof Dog){
            Dog d1 = (Dog) a;
            d1.lookDoor();
        }
        System.out.println("结束~~~~");
    }
}

跑的贼溜~~~~~
在看!!!
在看!!!
---------------------
预备~~~
跑的贼溜~~~~~
在看!!!
结束~~~~

内部类

内部类就是定义在一个类里面的类,里面的类可以理解成(寄生),外部类可以理解成(宿主)

public class People{
    // 内部类
    public class Heart{
    }
}

静态内部类

  • 有static修饰,属于外部类本身。
  • 它的特点和使用与普通类是完全一样的,类有的成分它都有,只是位置在别人里面而已
  • 可以直接访问外部类的静态成员,不能直接访问外部类的实例成员
public class Outer{
        // 静态成员内部类
        public static class Inner{
        }
}

静态内部类创建对象的格式

格式:外部类名.内部类名 对象名 = new 外部类名.内部类构造器;
范例:Outer.Inner in =  new Outer.Inner();

成员内部类

  • 无static修饰,属于外部类的对象。
  • JDK16之前,成员内部类中不能定义静态成员,JDK 16开始也可以定义静态成员了
  • 可以直接访问外部类的静态成员,实例方法中可以直接访问外部类的实例成员
public class Outer {
    // 成员内部类
    public class Inner {
    
    }
}

成员内部类创建对象的格式

格式:外部类名.内部类名 对象名 = new  外部类构造器.new 内部类构造器();
范例:Outer.Inner in =  new Outer().new Inner();

局部内部类

  • 局部内部类放在方法、代码块、构造器等执行体中。
  • 局部内部类的类文件名为: 外部类$N内部类.class

匿名内部类

本质上是一个没有名字的局部内部类,定义在方法中、代码块中、等。
作用:方便创建子类对象,最终目的为了简化代码编写。

new 类|抽象类名|或者接口名() {
    重写方法;
};
Animal a = new Animal() {
    public void run() {
    }
};
a. run();
public class Test {
    public static void main(String[] args) {
        Animal a = new Animal(){
            @Override
            public void run() {
                System.out.println("老虎跑的块~~~");
            }
        };
        a.run();
    }
}

//class Tiger extends Animal{
//    @Override
//    public void run() {
//        System.out.println("老虎跑的块~~~");
//    }
//}

abstract class Animal{
    public abstract void run();
}

匿名内部类在开发中的使用形式了解

某个学校需要让老师,学生,运动员一起参加游泳比赛

/*游泳接口*/
public interface Swimming {
    void swim();
}
/* 测试类*/
public class JumppingDemo {
    public static void main(String[] args) {
        //需求:goSwimming方法
    }
     
    // 定义一个方法让所有角色进来一起比赛
    public static void goSwimming(Swimming swimming) {
        swimming.swim();
    }
}

API

  • API(Application Programming interface)  应用程序编程接口。
  • 简单来说:就是Java帮我们已经写好的一些方法,我们直接拿过来用就可以了。

Object类

  • Object类的方法是一切子类对象都可以直接使用的,所以我们要学习Object类的方法。
  • 一个类要么默认继承了Object类,要么间接继承了Object类,Object类是Java中的祖宗类

ObjecttoString方法

父类toString()方法存在的意义就是为了被子类重写,以便返回对象的内容信息,而不是地址信息!! 

Student s = new Student("周雄", '男', 19);
System.out.println(s);

toS+tab键快速重写对象中toString方法

package com.itheima.d9_api_object;

import java.util.Objects;

public class Student { //extends Object{
    private String name;
    private char sex;
    private int age;

    public Student() {
    }

    public Student(String name, char sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sex=" + sex +
                ", age=" + age +
                '}';
    }
}


package com.itheima.d9_api_object;

/**
    目标:掌握Object类中toString方法的使用。
 */
public class Test1 {
    public static void main(String[] args) {
        Student s = new Student("周雄", '男', 19);
        // 直接输出对象变量,默认可以省略toString调用不写的
        System.out.println(s);
    }
}

Student{name='周雄', sex=男, age=19}

Objectequals方法

父类equals方法存在的意义就是为了被子类重写,以便子类自己来定制比较规则

Objects.equals(s1, s2)
package com.itheima.d9_api_object;

import java.util.Objects;

public class Student { //extends Object{
    private String name;
    private char sex;
    private int age;

    public Student() {
    }

    public Student(String name, char sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    /**
     定制相等规则。
     两个对象的内容一样就认为是相等的
     s1.equals(s2)
     比较者:s1 == this
     被比较者: s2 ==> o
     */
    @Override
    public boolean equals(Object o) {
        // 1、判断是否是同一个对象比较,如果是返回true。
        if (this == o) return true;
        // 2、如果o是null返回false  如果o不是学生类型返回false  ...Student !=  ..Pig
        if (o == null || this.getClass() != o.getClass()) return false;
        // 3、说明o一定是学生类型而且不为null
        Student student = (Student) o;
        return sex == student.sex && age == student.age && Objects.equals(name, student.name);
    }


    /**
       自己重写equals,自己定制相等规则。
        两个对象的内容一样就认为是相等的
     s1.equals(s2)
     比较者:s1 == this
     被比较者: s2 ==> o
     */
 /*   @Override
    public boolean equals(Object o){
        // 1、判断o是不是学生类型
        if(o instanceof Student){
            Student s2 = (Student) o;
            // 2、判断2个对象的内容是否一样。
//            if(this.name.equals(s2.name) &&
//                 this.age == s2.age && this.sex == s2.sex){
//                return true;
//            }else {
//                return false;
//            }
            return this.name.equals(s2.name) && this.age == s2.age
                    && this.sex == s2.sex ;

        }else {
            // 学生只能和学生比较,否则结果一定是false
            return false;
        }
    }*/


    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sex=" + sex +
                ", age=" + age +
                '}';
    }
}


package com.itheima.d9_api_object;

import java.util.Objects;

/**
    目标:掌握Object类中equals方法的使用。
 */
public class Test2 {
    public static void main(String[] args) {
        Student s1 = new Student("周雄", '男', 19);
        Student s2 = new Student("周雄", '男', 19);
        // equals默认是比较2个对象的地址是否相同,子类重写后会调用子类重写的来比较内容是否相同。
        System.out.println(s1.equals(s2));
        System.out.println(s1 == s2);

        System.out.println(Objects.equals(s1, s2));
    }
}

StringBuilder

StringBuilder是一个可变的字符串类,我们可以把它看成是一个对象容器。

拼接、反转字符串建议使用StringBuilder:

String :内容是不可变的、拼接字符串性能差。

StringBuilder:内容是可变的、拼接字符串性能好、代码优雅。

使用情况

定义字符串使用String

拼接、修改等操作字符串使用StringBuilder

public StringBuilder()

创建一个空白的可变的字符串对象,不包含任何内容

public StringBuilder(String str)

创建一个指定字符串内容的可变字符串对象

public StringBuilder append(任意类型)

添加数据并返回StringBuilder对象本身

public StringBuilder reverse()

将对象的内容反转

public int length()

返回对象内容长度

public String toString()

通过toString()就可以实现把StringBuilder转换为String

public class Test {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        sb.append("a");
        sb.append("b");
        sb.append("c");
        System.out.println(sb);
    }
}

Math类

包含执行基本数字运算的方法,Math类没有提供公开的构造器。

如何使用类中的成员呢?看类的成员是否都是静态的,如果是,通过类名就可以直接调用

Math 类的常用方法

方法名

说明

public static int abs​(int a)

获取参数绝对值

public static double ceil​(double a)

向上取整

public static double floor​(double a)

向下取整

public static int round​(float a)

四舍五入

public static int max​(int a,int b)

获取两个int值中的较大值

public static double pow​(double a,double b)

返回ab次幂的值

public static double random​()

返回值为double的随机值,范围[0.0,1.0)

package com.itheima.d12_math;

/**
    目标:Math类的使用。
    Math用于做数学运算。
    Math类中的方法全部是静态方法,直接用类名调用即可。
    方法:
          方法名                                          说明
          public static int abs(int a)                   获取参数a的绝对值:
          public static double ceil(double a)            向上取整
          public static double floor(double a)           向下取整
          public static double pow(double a, double b)   获取a的b次幂
          public static long round(double a)             四舍五入取整
    小结:
          记住。
 */
public class MathDemo {
    public static void main(String[] args) {
        // 1.取绝对值:返回正数
        System.out.println(Math.abs(10)); // 10
        System.out.println(Math.abs(-10.3)); // 10.3

        // 2.向上取整: 5
        System.out.println(Math.ceil(4.00000001)); // 5.0
        System.out.println(Math.ceil(4.0)); // 4.0
        // 3.向下取整:4
        System.out.println(Math.floor(4.99999999)); // 4.0
        System.out.println(Math.floor(4.0)); // 4.0

        // 4.求指数次方
        System.out.println(Math.pow(2 , 3)); // 2^3 = 8.0
        // 5.四舍五入 10
        System.out.println(Math.round(4.49999)); // 4
        System.out.println(Math.round(4.500001)); // 5

        System.out.println(Math.random());  // 0.0 - 1.0 (包前不包后)

        // 拓展: 3 - 9 之间的随机数  (0 - 6) + 3
        //  [0 - 6] + 3
        int data =  (int)(Math.random() * 7) + 3;
        System.out.println(data);


    }
}

System

System也是一个工具类,代表了当前系统,提供了一些与系统相关的方法。

System 类的常用方法

方法名

说明

public static void exit​(int status)

终止当前运行的 Java 虚拟机,非零表示异常终止

public static long currentTimeMillis​()

返回当前系统的时间毫秒值形式

public static void arraycopy(数据源数组, 起始索引, 目的地数组, 起始索引, 拷贝个数)

数组拷贝

终止当前运行的 Java 虚拟机 

System.exit(0); // JVM终止!

 返回当前系统的时间毫秒值形式

long time = System.currentTimeMillis();
System.out.println(time);//1643334543214

进行时间的计算:性能分析 

        long startTime = System.currentTimeMillis();
        // 进行时间的计算:性能分析
        for (int i = 0; i < 100000; i++) {
            System.out.println("输出:" + i);
        }
        long endTime = System.currentTimeMillis();
        System.out.println((endTime - startTime)/1000.0 + "s");

做数组拷贝

        /**
         arraycopy(Object src,  int  srcPos,
         Object dest, int destPos,
         int length)
         参数一:被拷贝的数组
         参数二:从哪个索引位置开始拷贝
         参数三:复制的目标数组
         参数四:粘贴位置
         参数五:拷贝元素的个数
         */
        int[] arr1 = {10, 20, 30, 40, 50, 60, 70};
        int[] arr2 = new int[6]; // [0, 0, 0, 0, 0, 0] ==>  [0, 0, 40, 50, 60, 0]
        System.arraycopy(arr1, 3, arr2, 2, 3);
        System.out.println(Arrays.toString(arr2));

[0, 0, 40, 50, 60, 0]

BigDecimal

用于解决浮点型运算精度失真的问题

创建对象BigDecimal封装浮点型数据(最好的方式是调用方法)

public static BigDecimal valueOf(double val):   包装浮点数成为BigDecimal对象

方法名

说明

public BigDecimal add(BigDecimal b)

加法

public BigDecimal subtract(BigDecimal b)

减法

public BigDecimal multiply(BigDecimal b)

乘法

public BigDecimal divide(BigDecimal b)

除法

public BigDecimal divide (另一个BigDecimal对象,精确几位,舍入模式)

除法

package com.itheima.d14_bigdecimal;


import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;

/**
    目标:BigDecimal大数据类。

    引入:
        浮点型运算的时候直接+  * / 可能会出现数据失真(精度问题)。
        BigDecimal可以解决浮点型运算数据失真的问题。

    BigDicimal类:
        包:java.math.
        创建对象的方式(最好的方式:)
              public static BigDecimal valueOf(double val) :包装浮点数成为大数据对象。
        方法声明
              public BigDecimal add(BigDecimal value)       加法运算
              public BigDecimal subtract(BigDecimal value)  减法运算 
              public BigDecimal multiply(BigDecimal value)  乘法运算 
              public BigDecimal divide(BigDecimal value)    除法运算
              public double doubleValue(): 把BigDecimal转换成double类型。
 */
public class BigDecimalDemo {
    public static void main(String[] args) {
        // 浮点型运算的时候直接+  * / 可能会出现数据失真(精度问题)。
        System.out.println(0.09 + 0.01);
        System.out.println(1.0 - 0.32);
        System.out.println(1.015 * 100);
        System.out.println(1.301 / 100);

        System.out.println("-------------------------");
        double a = 0.1;
        double b = 0.2;
        double c = a + b;
        System.out.println(c);
        System.out.println("--------------------------");
        // 包装浮点型数据成为大数据对象 BigDeciaml
        BigDecimal a1 = BigDecimal.valueOf(a);
        BigDecimal b1 = BigDecimal.valueOf(b);
        BigDecimal c1 = a1.add(b1);
        // BigDecimal c1 = a1.subtract(b1);
        // BigDecimal c1 = a1.multiply(b1);
        // BigDecimal c1 = a1.divide(b1);
        System.out.println(c1);

        // 目的:double
        double rs = c1.doubleValue();
        System.out.println(rs);

        // 注意事项:BigDecimal是一定要精度运算的
        BigDecimal a11 = BigDecimal.valueOf(10.0);
        BigDecimal b11 = BigDecimal.valueOf(3.0);
        /**
           参数一:除数 参数二:保留小数位数  参数三:舍入模式
         */
        BigDecimal c11 = a11.divide(b11, 2, RoundingMode.HALF_UP); // 3.3333333333
        System.out.println(c11);


        System.out.println("-------------------");
    }
}

0.09999999999999999
0.6799999999999999
101.49999999999999
0.013009999999999999
-------------------------
0.30000000000000004
--------------------------
0.3
0.3
3.33
-------------------

Date :当前所在系统日期时间信息

Date d = new Date();    //代表系统此刻日期时间对象
long time = d.getTime();    //获取时间毫秒值

//当前时间往后走 1小时  121s
long time = System.currentTimeMillis();
time += (60 * 60 + 121) * 1000;

//把时间毫秒值转换成对应的日期对象
Date d = new Date(time);

//修改时间
Date d = new Date();
d3.setTime(time);

Fri Jan 28 10:13:30 HKT 2022
1643336010844 

SimpleDateFormat 类:日期时间的格式化操作

Fri Jan 28 10:13:30 CST 2022--->2022年12810:13:30

  •   y    年
  •   M    月
  •   d    日
  •   H    时
  •   m    分
  •   s    秒
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a");
String rs = sdf.format(d);

long time1 = System.currentTimeMillis()
String rs2 = sdf.format(time1);
        // 1、日期对象
        Date d = new Date();
        System.out.println(d);

        // 2、格式化这个日期对象 (指定最终格式化的形式)
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a");
        // 3、开始格式化日期对象成为喜欢的字符串形式
        String rs = sdf.format(d);
        System.out.println(rs);

        System.out.println("----------------------------");

        // 4、格式化时间毫秒值
        // 需求:请问121秒后的时间是多少
        long time1 = System.currentTimeMillis() + 121 * 1000;
        String rs2 = sdf.format(time1);
        System.out.println(rs2);

Fri Jan 28 10:16:17 HKT 2022
2022年01月28日 10:16:17 周五 上午
----------------------------
2022年01月28日 10:18:18 周五 上午

SimpleDateFormat解析字符串时间成为日期对象

Date d = sdf.parse(dateStr);
// 目标: 学会使用SimpleDateFormat解析字符串时间成为日期对象。
        // 有一个时间 2021年08月06日 11:11:11 往后 2天 14小时 49分 06秒后的时间是多少。
        // 1、把字符串时间拿到程序中来
        String dateStr = "2021年08月06日 11:11:11";

        // 2、把字符串时间解析成日期对象(本节的重点):形式必须与被解析时间的形式完全一样,否则运行时解析报错!
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        Date d = sdf.parse(dateStr);

        // 3、往后走2天 14小时 49分 06秒
        long time = d.getTime() + (2L*24*60*60 + 14*60*60 + 49*60 + 6) * 1000;

        // 4、格式化这个时间毫秒值就是结果
        System.out.println(sdf.format(time));

Calendar:系统此刻日期对应的日历对象

Calendar是一个抽象类,不能直接创建对象。

    Calendar日历类创建日历对象的语法:
        Calendar rightNow = Calendar.getInstance();
    Calendar的方法:
        1.public static Calendar getInstance(): 返回一个日历类的对象。
        2.public int get(int field):取日期中的某个字段信息。
        3.public void set(int field,int value):修改日历的某个字段信息。
        4.public void add(int field,int amount):为某个字段增加/减少指定的值
        5.public final Date getTime(): 拿到此刻日期对象。
        6.public long getTimeInMillis(): 拿到此刻时间毫秒值
package com.itheima.d3_calendar;

import javax.xml.crypto.Data;
import java.util.Calendar;
import java.util.Date;

public class CalendarDemo{
    public static void main(String[] args) {
        // 1、拿到系统此刻日历对象
        Calendar cal = Calendar.getInstance();
        System.out.println(cal);

        // 2、获取日历的信息:public int get(int field):取日期中的某个字段信息。
        int year = cal.get(Calendar.YEAR);
        System.out.println(year);

        int mm = cal.get(Calendar.MONTH) + 1;
        System.out.println(mm);

        int days = cal.get(Calendar.DAY_OF_YEAR) ;
        System.out.println(days);

        // 3、public void set(int field,int value):修改日历的某个字段信息。
        // cal.set(Calendar.HOUR , 12);
        // System.out.println(cal);

        // 4.public void add(int field,int amount):为某个字段增加/减少指定的值
        // 请问64天后是什么时间
        cal.add(Calendar.DAY_OF_YEAR , 64);
        cal.add(Calendar.MINUTE , 59);

        //  5.public final Date getTime(): 拿到此刻日期对象。
        Date d = cal.getTime();
        System.out.println(d);

        //  6.public long getTimeInMillis(): 拿到此刻时间毫秒值
        long time = cal.getTimeInMillis();
        System.out.println(time);

    }
}

java.util.GregorianCalendar[time=1643336750682,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo

[id="Asia/Hong_Kong",offset=28800000,dstSavings=0,useDaylight=false,transitions=71,lastRule=null],

firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2022,MONTH=0,WEEK_OF_YEAR=5,WEEK_OF_MONTH=5,

DAY_OF_MONTH=28,DAY_OF_YEAR=28,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=4,AM_PM=0,HOUR=10,

HOUR_OF_DAY=10,MINUTE=25,SECOND=50,MILLISECOND=682,ZONE_OFFSET=28800000,DST_OFFSET=0]
2022
1
28
Sat Apr 02 11:24:50 HKT 2022
1648869890682

JDK8新增日期类

LocalDate:不包含具体时间的日期。
LocalTime:不含日期的时间。
LocalDateTime:包含了日期及时间。
Instant:代表的是时间戳。
DateTimeFormatter 用于做时间的格式化和解析的
Duration:用于计算两个“时间”间隔
Period:用于计算两个“日期”间隔

Instant时间戳

  • 时间戳是包含日期和时间的,与java.util.Date很类似,事实上Instant就是类似JDK8 以前的Date。
  • Instant和Date这两个类可以进行转换。
package com.itheima.d4_jdk8_time;

import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;

public class Demo05Instant {
    public static void main(String[] args) {
        // 1、得到一个Instant时间戳对象
        Instant instant = Instant.now();
        System.out.println(instant);

        // 2、系统此刻的时间戳怎么办?
        Instant instant1 = Instant.now();
        System.out.println(instant1.atZone(ZoneId.systemDefault()));

        // 3、如何去返回Date对象
        Date date = Date.from(instant);
        System.out.println(date);

        Instant i2 = date.toInstant();
        System.out.println(i2);
    }
}

2022-01-28T02:34:50.645395800Z
2022-01-28T10:34:50.654372600+08:00[Asia/Hong_Kong]
Fri Jan 28 10:34:50 HKT 2022
2022-01-28T02:34:50.645Z

DateTimeFormatter

日期与时间格式器,正反都能调用format方法

package com.itheima.d4_jdk8_time;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Demo06DateTimeFormat {
    public static void main(String[] args) {
        // 本地此刻  日期时间 对象
        LocalDateTime ldt = LocalDateTime.now();
        System.out.println(ldt);

        // 解析/格式化器
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss EEE a");
        // 正向格式化
        System.out.println(dtf.format(ldt));
        // 逆向格式化
        System.out.println(ldt.format(dtf));

        // 解析字符串时间
        DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 解析当前字符串时间成为本地日期时间对象
        LocalDateTime ldt1 = LocalDateTime.parse("2019-11-11 11:11:11" ,  dtf1);
        System.out.println(ldt1);
        System.out.println(ldt1.getDayOfYear());
    }
}

2022-01-28T10:36:24.292803800
2022-01-28 10:36:24 周五 上午
2022-01-28 10:36:24 周五 上午
2019-11-11T11:11:11
315

Duration:  用于计算两个“时间”间隔

在Java8中,我们可以使用以下类来计算时间间隔差异:java.time.Duration
提供了使用基于时间的值测量时间量的方法。
用于 LocalDateTime 之间的比较。也可用于 Instant 之间的比较。

        // 本地日期时间对象。
        LocalDateTime today = LocalDateTime.now();
        System.out.println(today);

        // 出生的日期时间对象
        LocalDateTime birthDate = LocalDateTime.of(2021,8
                ,06,01,00,00);

        System.out.println(birthDate);

        Duration duration = Duration.between(  today , birthDate);//第二个参数减第一个参数

        System.out.println(duration.toDays());//两个时间差的天数
        System.out.println(duration.toHours());//两个时间差的小时数
        System.out.println(duration.toMinutes());//两个时间差的分钟数
        System.out.println(duration.toMillis());//两个时间差的毫秒数
        System.out.println(duration.toNanos());//两个时间差的纳秒数

Period:      用于计算两个“日期”间隔

在Java8中,我们可以使用以下类来计算日期间隔差异:java.time.Period
主要是 Period 类方法 getYears(),getMonths() 和 getDays() 来计算,只能精确到年月日。
用于 LocalDate 之间的比较。

        // 当前本地 年月日
        LocalDate today = LocalDate.now();
        System.out.println(today);//

        // 生日的 年月日
        LocalDate birthDate = LocalDate.of(1998, 10, 13);
        System.out.println(birthDate);

        Period period = Period.between(birthDate, today);//第二个参数减第一个参数

        System.out.println(period.getYears());
        System.out.println(period.getMonths());
        System.out.println(period.getDays());

ChronoUnit类可用于在单个时间单位内测量一段时间

这个工具类是最全的了,可以用于比较所有的时间单位

package com.itheima.d4_jdk8_time;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

public class Demo09ChronoUnit {
    public static void main(String[] args) {
        // 本地日期时间对象:此刻的
        LocalDateTime today = LocalDateTime.now();
        System.out.println(today);

        // 生日时间
        LocalDateTime birthDate = LocalDateTime.of(1990,10,1,
                10,50,59);
        System.out.println(birthDate);

        System.out.println("相差的年数:" + ChronoUnit.YEARS.between(birthDate, today));
        System.out.println("相差的月数:" + ChronoUnit.MONTHS.between(birthDate, today));
        System.out.println("相差的周数:" + ChronoUnit.WEEKS.between(birthDate, today));
        System.out.println("相差的天数:" + ChronoUnit.DAYS.between(birthDate, today));
        System.out.println("相差的时数:" + ChronoUnit.HOURS.between(birthDate, today));
        System.out.println("相差的分数:" + ChronoUnit.MINUTES.between(birthDate, today));
        System.out.println("相差的秒数:" + ChronoUnit.SECONDS.between(birthDate, today));
        System.out.println("相差的毫秒数:" + ChronoUnit.MILLIS.between(birthDate, today));
        System.out.println("相差的微秒数:" + ChronoUnit.MICROS.between(birthDate, today));
        System.out.println("相差的纳秒数:" + ChronoUnit.NANOS.between(birthDate, today));
        System.out.println("相差的半天数:" + ChronoUnit.HALF_DAYS.between(birthDate, today));
        System.out.println("相差的十年数:" + ChronoUnit.DECADES.between(birthDate, today));
        System.out.println("相差的世纪(百年)数:" + ChronoUnit.CENTURIES.between(birthDate, today));
        System.out.println("相差的千年数:" + ChronoUnit.MILLENNIA.between(birthDate, today));
        System.out.println("相差的纪元数:" + ChronoUnit.ERAS.between(birthDate, today));
    }
}

2022-01-28T10:41:03.186356600
1990-10-01T10:50:59
相差的年数:31
相差的月数:375
相差的周数:1634
相差的天数:11441
相差的时数:274607
相差的分数:16476470
相差的秒数:988588204
相差的毫秒数:988588204186
相差的微秒数:988588204186356
相差的纳秒数:988588204186356600
相差的半天数:22883
相差的十年数:3
相差的世纪(百年)数:0
相差的千年数:0
相差的纪元数:0

包装类

其实就是8种基本数据类型对应的引用类型

Java为了实现一切皆对象,为8种基本类型提供了对应的引用类型。

后面的集合和泛型其实也只能支持包装类型,不支持基本数据类型

基本数据类型

引用数据类型

byte

Byte

short

Short

int

Integer

long

Long

char

Character

float

Float

double

Double

boolean

Boolean

自动装箱基本类型的数据和变量可以直接赋值给包装类型的变量

自动拆箱:包装类型的变量可以直接赋值给基本数据类型的变量

包装类的特有功能

  • 包装类的变量的默认值可以是null,容错率更高。
  • 可以把基本类型的数据转换成字符串类型(用处不大)
  • 可以把字符串类型的数值转换成真实的数据类型(真的很有用)
int age = Integer.valueOf(number);
double score = Double.valueOf(number1);
package com.itheima.d5_integer;

/**
    目标:明白包装类的概念,并使用。
 */
public class Test {
    public static void main(String[] args) {
        int a = 10;
        Integer a1 = 11;
        Integer a2 = a; // 自动装箱
        System.out.println(a);
        System.out.println(a1);

        Integer it = 100;
        int it1 = it; // 自动拆箱
        System.out.println(it1);

        double db = 99.5;
        Double db2 = db; // 自动装箱了
        double db3 = db2; // 自动拆箱
        System.out.println(db3);

        // int age = null; // 报错了!
        Integer age1 = null;
        Integer age2 = 0;

        System.out.println("-----------------");
        // 1、包装类可以把基本类型的数据转换成字符串形式。(没啥用)
        Integer i3 = 23;
        String rs = i3.toString();
        System.out.println(rs + 1);

        String rs1 = Integer.toString(i3);
        System.out.println(rs1 + 1);

        // 可以直接+字符串得到字符串类型
        String rs2 = i3 + "";
        System.out.println(rs2 + 1);

        System.out.println("-----------------");

        String number = "23";
        //转换成整数
        // int age = Integer.parseInt(number);
        int age = Integer.valueOf(number);
        System.out.println(age + 1);

        String number1 = "99.9";
        //转换成小数
        //double score = Double.parseDouble(number1);
        double score = Double.valueOf(number1);
        System.out.println(score + 0.1);
    }
}

10
11
100
99.5
-----------------
231
231
231
-----------------
24
100.0

正则表达式

public boolean matches(String regex):判断是否与正则表达式匹配,匹配返回true

字符类(默认匹配一个字符)

[abc]         只能是a, b, c

[^abc]         除了a, b, c之外的任何字符

[a-zA-Z]               az AZ,包括(范围)

[a-d[m-p]]         ad,或m通过p:([a-dm-p]联合)

[a-z&&[def]]         d, e, f(交集)

[a-z&&[^bc]]         az,除了bc:([ad-z]减法)

[a-z&&[^m-p]]     az,除了mp:([a-lq-z]减法)

预定义的字符类(默认匹配一个字符)

任何字符

\d  一个数字: [0-9]

\D  非数字: [^0-9]

\s  一个空白字符: [ \t\n\x0B\f\r]

\S  非空白字符: [^\s]

\w  [a-zA-Z_0-9] 英文、数字、下划线

\W  [^\w] 一个非单词字符

贪婪的量词(配合匹配多个字符)

X?  X , 一次或根本不

X*  X,零次或多次

X+  X , 一次或多次

X {n}  X,正好n

X {n, }  X,至少n

X {n,m}  X,至少n但不超过m

        // 只能是 a  b  c
        System.out.println("a".matches("[abc]")); // true
        System.out.println("z".matches("[abc]")); // false

        // 不能出现a  b  c
        System.out.println("a".matches("[^abc]")); // false
        System.out.println("z".matches("[^abc]")); // true

        System.out.println("a".matches("\\d")); // false
        System.out.println("3".matches("\\d")); // true
        System.out.println("333".matches("\\d")); // false
        System.out.println("z".matches("\\w")); // true
        System.out.println("2".matches("\\w")); // true
        System.out.println("21".matches("\\w")); // false
        System.out.println("你".matches("\\w")); //false
        System.out.println("你".matches("\\W")); // true
        System.out.println("---------------------------------");
        //  以上正则匹配只能校验单个字符。

        // 校验密码
        // 必须是数字 字母 下划线 至少 6位
        System.out.println("2442fsfsf".matches("\\w{6,}"));
        System.out.println("244f".matches("\\w{6,}"));

        // 验证码 必须是数字和字符  必须是4位
        System.out.println("23dF".matches("[a-zA-Z0-9]{4}"));
        System.out.println("23_F".matches("[a-zA-Z0-9]{4}"));
        System.out.println("23dF".matches("[\\w&&[^_]]{4}"));
        System.out.println("23_F".matches("[\\w&&[^_]]{4}"));

 public String replaceAll(String regex,String newStr)

按照正则表达式匹配的内容进行替换

public String[] split(String regex)

按照正则表达式匹配的内容进行分割字符串,反回一个字符串数组。

        String names = "小路dhdfhdf342蓉儿43fdffdfbjdfaf小何";

        String[] arrs = names.split("\\w+");
        for (int i = 0; i < arrs.length; i++) {
            System.out.println(arrs[i]);
        }

        String names2 = names.replaceAll("\\w+", "  ");
        System.out.println(names2);

小路
蓉儿
小何
小路  蓉儿  小何

正则表达式爬取信息中的内容

package com.itheima.d6_regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
    拓展:正则表达式爬取信息中的内容。(了解)
 */
public class RegexDemo05 {
    public static void main(String[] args) {
        String rs = "来黑马程序学习Java,电话020-43422424,或者联系邮箱" +
                "[email protected],电话18762832633,0203232323" +
                "邮箱[email protected],400-100-3233 ,4001003232";

        // 需求:从上面的内容中爬取出 电话号码和邮箱。
        // 1、定义爬取规则,字符串形式
        String regex = "(\\w{1,30}@[a-zA-Z0-9]{2,20}(\\.[a-zA-Z0-9]{2,20}){1,2})|(1[3-9]\\d{9})" +
                "|(0\\d{2,6}-?\\d{5,20})|(400-?\\d{3,9}-?\\d{3,9})";

        // 2、把这个爬取规则编译成匹配对象。
        Pattern pattern = Pattern.compile(regex);

        // 3、得到一个内容匹配器对象
        Matcher matcher = pattern.matcher(rs);

        // 4、开始找了
        while (matcher.find()) {
            String rs1 = matcher.group();
            System.out.println(rs1);
        }

    }
}

020-43422424
[email protected]
18762832633
0203232323
[email protected]
400-100-3233
4001003232

Arrays类:数组操作工具类,专门用于操作数组元素的。

public static String toString​(类型[] a)

返回数组的内容(字符串形式)

public static void sort​(类型[] a)

对数组进行默认升序排序

public static  void sort​(类型[] a, Comparator c)

使用比较器对象自定义排序

public static int binarySearch​(int[] a, int key)

二分搜索数组中的数据,存在返回索引,不存在返回-1

package com.itheima.d7_arrays;

import java.util.Arrays;

public class ArraysDemo1 {
    public static void main(String[] args) {
        // 目标:学会使用Arrays类的常用API ,并理解其原理
        int[] arr = {10, 2, 55, 23, 24, 100};
        System.out.println(arr);

        // 1、返回数组内容的 toString(数组)
//        String rs = Arrays.toString(arr);
//        System.out.println(rs);

        System.out.println(Arrays.toString(arr));

        // 2、排序的API(默认自动对数组元素进行升序排序)
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));

        // 3、二分搜索技术(前提数组必须排好序才支持,否则出bug)
        int index = Arrays.binarySearch(arr, 55);
        System.out.println(index);

        // 返回不存在元素的规律: - (应该插入的位置索引 + 1)
        int index2 = Arrays.binarySearch(arr, 22);
        System.out.println(index2);


        // 注意:数组如果没有排好序,可能会找不到存在的元素,从而出现bug!!
        int[] arr2 = {12, 36, 34, 25 , 13,  24,  234, 100};
        System.out.println(Arrays.binarySearch(arr2 , 36));
    }

}

[I@776ec8df
[10, 2, 55, 23, 24, 100]
[2, 10, 23, 24, 55, 100]
4
-3
-7

public static void sort​(类型[] a)

对数组进行默认升序排序

public static  void sort​(类型[] a, Comparator c)

使用比较器对象自定义排序

package com.itheima.d7_arrays;

import java.util.Arrays;
import java.util.Comparator;

public class ArraysDemo2 {
    public static void main(String[] args) {
        // 目标:自定义数组的排序规则:Comparator比较器对象。
        // 1、Arrays的sort方法对于有值特性的数组是默认升序排序
        int[] ages = {34, 12, 42, 23};
        Arrays.sort(ages);
        System.out.println(Arrays.toString(ages));

        // 2、需求:降序排序!(自定义比较器对象,只能支持引用类型的排序!!)
        Integer[] ages1 = {34, 12, 42, 23};
        /**
           参数一:被排序的数组 必须是引用类型的元素
           参数二:匿名内部类对象,代表了一个比较器对象。
         */
        Arrays.sort(ages1, new Comparator() {
            @Override
            public int compare(Integer o1, Integer o2) {
                // 指定比较规则。
//                if(o1 > o2){
//                    return 1;
//                }else if(o1 < o2){
//                    return -1;
//                }
//                return 0;
                // return o1 - o2; // 默认升序
                return o2 - o1; //  降序
            }
        });
        System.out.println(Arrays.toString(ages1));

        System.out.println("-------------------------");
        Student[] students = new Student[3];
        students[0] = new Student("吴磊",23 , 175.5);
        students[1] = new Student("谢鑫",18 , 185.5);
        students[2] = new Student("王亮",20 , 195.5);
        System.out.println(Arrays.toString(students));

        // Arrays.sort(students);  // 直接运行奔溃
        Arrays.sort(students, new Comparator() {
            @Override
            public int compare(Student o1, Student o2) {
                // 自己指定比较规则
                // return o1.getAge() - o2.getAge(); // 按照年龄升序排序!
                // return o2.getAge() - o1.getAge(); // 按照年龄降序排序!!
                // return Double.compare(o1.getHeight(), o2.getHeight()); // 比较浮点型可以这样写 升序
                return Double.compare(o2.getHeight(), o1.getHeight()); // 比较浮点型可以这样写  降序
            }
        });
        System.out.println(Arrays.toString(students));


    }
}
package com.itheima.d7_arrays;

public class Student {
    private String name;
    private int age;
    private double height;

    public Student() {
    }

    public Student(String name, int age, double height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                '}';
    }
}

常见算法

冒泡排序

package com.itheima.d8_sort_binarysearch;

import java.util.Arrays;

/**
    目标:学会使用选择排序的方法对数组进行排序。
 */
public class Test1 {
    public static void main(String[] args) {
        // 1、定义数组
        int[] arr = {5, 1, 3, 2};
        //           0  1  2  3

        // 2、定义一个循环控制选择几轮: arr.length - 1
        for (int i = 0; i < arr.length - 1; i++) {
            // i = 0   j =  1  2  3
            // i = 1   j =  2  3
            // i = 2   j =  3
            // 3、定义内部循环,控制选择几次
            for (int j = i + 1; j < arr.length; j++) {
                // 当前位:arr[i]
                // 如果有比当前位数据更小的,则交换
                if(arr[i] > arr[j]) {
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}

选择排序

二分查找

  • 定义变量记录左边和右边位置。
  • 使用while循环控制查询(条件是左边位置<=右边位置)
  • 循环内部获取中间元素索引
  • 判断当前要找的元素如果大于中间元素,左边位置=中间索引+1
  • 判断当前要找的元素如果小于中间元素,右边位置=中间索引-1
  • 判断当前要找的元素如果等于中间元素,返回当前中间元素索引
package com.itheima.d8_sort_binarysearch;

/**
    目标:理解二分搜索的原理并实现。
 */
public class Test2 {
    public static void main(String[] args) {
        // 1、定义数组
        int[] arr = {10, 14, 16, 25, 28, 30, 35, 88, 100};
        //                                            r
        //                                                l
        //
        System.out.println(binarySearch(arr , 35));
        System.out.println(binarySearch(arr , 350));
    }
    /**
     * 二分查找算法的实现
     * @param arr  排序的数组
     * @param data 要找的数据
     * @return  索引,如果元素不存在,直接返回-1
     */
    public static int binarySearch(int[] arr, int data){
        // 1、定义左边位置  和 右边位置
        int left = 0;
        int right = arr.length - 1;

        // 2、开始循环,折半查询。
        while (left <= right){
            // 取中间索引
            int middleIndex = (left + right) / 2;
            // 3、判断当前中间位置的元素和要找的元素的大小情况
            if(data > arr[middleIndex]) {
                // 往右边找,左位置更新为 = 中间索引+1
                left = middleIndex + 1;
            }else if(data < arr[middleIndex]) {
                // 往左边找,右边位置 = 中间索引 - 1
                right = middleIndex - 1;
            }else {
                return middleIndex;
            }
        }
        return -1; // 查无此元素
    }

}

Lambda简化匿名内部类的代码写法

Lambda表达式只能简化函数式接口的匿名内部类的写法形式

(匿名内部类被重写方法的形参列表) -> {
   被重写方法的方法体代码。
}
注:-> 是语法形式,无实际含义
package com.itheima.d9_lambda;

public class LambdaDemo2 {
    public static void main(String[] args) {
        // 目标:学会使用Lambda的标准格式简化匿名内部类的代码形式
        // 注意:Lambda只能简化接口中只有一个抽象方法的匿名内部类形式(函数式接口)
//        Swimming s1 = new Swimming() {
//            @Override
//            public void swim() {
//                System.out.println("老师游泳贼溜~~~~~");
//            }
//        };

//        Swimming s1 = () -> {
//            System.out.println("老师游泳贼溜~~~~~");
//        };

        Swimming s1 = () -> System.out.println("老师游泳贼溜~~~~~");
        go(s1);

        System.out.println("---------------------");
//        go(new Swimming() {
//            @Override
//            public void swim() {
//                System.out.println("学生游泳很开心~~~");
//            }
//        });

//        go(() ->{
//                System.out.println("学生游泳很开心~~~");
//        });

        go(() -> System.out.println("学生游泳很开心~~~"));


    }

    public static void go(Swimming s){
        System.out.println("开始。。。");
        s.swim();
        System.out.println("结束。。。");
    }
}

@FunctionalInterface // 一旦加上这个注解必须是函数式接口,里面只能有一个抽象方法
interface Swimming{
    void swim();
}

Lambda表达式的省略写法(进一步在Lambda表达式的基础上继续简化)

参数类型可以省略不写。

如果只有一个参数,参数类型可以省略,同时()也可以省略。

如果Lambda表达式的方法体代码只有一行代码。可以省略大括号不写,同时要省略分号!

如果Lambda表达式的方法体代码只有一行代码。可以省略大括号不写。此时,如果这行代码是return语句,必须省略return不写,同时也必须省略";"不写

你可能感兴趣的:(安卓开发,java,开发语言,后端)