Java

Overview

Introduce

TIP

Java 可运行于多个平台,如 Windows, Mac OS,及其他多种 UNIX 版本的系统。

Java 是平台独立的语言,用 Java 编写的应用程序不用修改就可以在不同的平台上运行。

Java 具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点,能够适应几乎任何类型的应用程序的需求。

HelloWorld

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

Ⅰ Basic Concepts

输入 & 输出

Output

System.out.print()                   // 不换行
System.out.println()                 // 换行
System.out.printf(str, var1, var2)   // 格式化字符串

Input

import java.util.Scanner;

Scanner sc = new Scanner(System.in);
String str = sc.nextLine();

//String str = new Scanner(System.in).nextLine();
nextByte()
nextShort()
nextInt()
nextLong()
nextFloat()
nextDouble()
nextBoolean()
next()         //word(不包括空格)
nextLine()    //complete line(可能包含空格)

hasNext()
hasNextInt()
hasNextDouble()

变量 & 常量

// 变量
int num = 12;
// final 常量
final double PI = 3.14;

// 多个变量
int i, j;
int a = 1, b = 2;

// 枚举
enum Color { red, blue, green };

基础数据类型

/**
 * 基础数据类型
 * 1.数字:
 *   a) 整数:  byte  short  `int`  long
 *   b) 浮点数:float `double`
 * 2.字符:char
 * 3.布尔:boolean (false  true)
 */

for example

int num = 12;
double pi = 3.14;
char c = 'p';
boolean flag = true;

所占字节大小

byte  short int long (1,2,4,8)
float double         (4,8)
char                 (2)
boolean(true/false)  (1)    (0/1不可替代true/false)

强制数据转换

// 强制类型转换(Type Casting)--> 会损失精度
int a = (int) 3.14;    //3

double b = 42.571;
System.out.println((int)b); //42

// 自动类型转换:不会丢失精度

整数取值范围

byte    // -128 ~ 127
short   // -32768 ~ 32767
int
long num = 10_000_000_000L;

float PI = 3.14F;   // 精度6-7位有效数字,很多情况下不能满足需求
  • 变量是对对象的引用

  • 局部变量(方法内):声明数据类型+初始化

  • 全局变量(类内):声明数据类型,有默认值,可静态初始化

  • 变量名不可重复,大小写敏感, 不能以数字开头,不能是关键字

  • 标志符:字母、数字、美元符$、下划线_

  • 源文件名:源文件名必须和类名相同,文件名的后缀为.java。

注释

// 单行注释
/* 多行注释 */

/**
 * 文档注释
 * @author coulsonzero
 * @version ${YEAR}-${MONTH}-${DAY} ${TIME}
 */

运算符

Math 算术 (+ - * / %)

1 + 2 + "hello" = "3hello"
15/3 = 5
15.0/3 = 5.0

赋值运算(+= -= *= /= %=)

// 如果右侧类型与左侧数据类型不通,则强制转换
long x += 5;
int x = (int) (x+5)

//java中后者数据类型如果与左侧不一致则报错
+== ...+...

自增自减 (x++ x-- ++x --x)

x++    (先赋值再递增)
++x    (先递增再赋值)


int x = 34;
int y = ++x; //y is 35
int i = 34;
int j = i++; //j is 34

逻辑(&& || !)

TIP

短路原理
&& 当左侧为Fasle,则不再执行右侧
|| 当左侧为True, 则不再执行右侧

关系运算(== != > >= < <= ?)

condition ? expression1 : expression2;
int max = a > b ? a : b;

Math

Math.sqrt(x)    //平方根
Math.pow(x,a)   //平方
Math.random()0-1之间的随机浮点数
Math.abs()
Math.round()
Math.ceil(7.3)  //8.0
Math.floor(7.7) //7.0
Math.max()
Math.min()
Math.PI

Ⅱ Conditions and Loops

1. 陈述语句

if (condition) {
    //statement;
} else if (condition) {
    ...
} else if (condition) {
    ...
} else {
    ...
}

/**
 * if:      至少一个
 * else if: 可以有多个
 * else:    可以没有
 * condition: 为了使变量能够在循环外重复使用,变量类型一般在循环外定义!
 */
switch (expression) {
    case value1:
        // statements
        break;
    case value2:
        ...;
        break;
    case value3:
        ...;
        break;    // optional
    default:      // optional
        ...;
        break;
}
int day = 2;
String dayType = switch(day) {
    case 1, 2, 3, 4, 5 -> "Working day";
    case 6, 7 -> "Weekend";
    default -> "Invalid";
};

WARNING

Switch

开始->case 1->case 2->case n->结束 🔚

存在 case ... 符合条件则跳出,否则继续往下判断

没有break则继续穿透

default 可选,总是位于最后一段.如果所有 case 都为 False,则执行 default

2. 循环语句

for (init; condition; increment) {
    // statement(s)
}

// 如果希望在循环体外使用计数器的最终值,则在循环体外申明变量类型
for(int i = 0; i < s.length; i++) {
    // statement(s)
}

// 双指针
for (int l = 0, r = s.length-1; l < r; l++, r--) {
    // statement(s)
}
for (int v : nums) {
    // statement(s)
}
int i = 0;
while (condition) {
    // statement;
    i++;
}
// 至少执行一次
do {
    // statement(s)
    i++;
}
while (condition);

Loop Control Statements

break     // 跳出循环体
continue  // 跳至此次循环进入下一循环
goto      // 跳出指定循环体

字符串

APIStringStringBulidapi
长度length()length()
输出toString()
字符charAt()append()/insert()
索引indexOf()delete
包含contains()reverse()反转
子串substring()
拼接contact()/String.join()
分割split()
替换replace()replace
重复repeat()
除空strip()/trim()
开头startsWith()
结尾endsWith()
相等equals()/equalsIgnoreCase()
为空isEmpty()/Blank()
大写toUpperCase()
小写toLowCase()
转字符数组toCharArray()
整数转字符串String.valueOf()/Integer.toString()
字符串转整数Integer.parseInt()

String

TIP

String 不可变:内容不可变,引用可变 ==> 节省内存占用

字符串初始化

String name = "Coulson";

字符串Api

// String Api:
长度:s.length()
字符:s.chartAt(int i)
索引:s.indexOf(string substr)

子串:s.substring(int start, int end)
拼接:s.concat(string s2)
重复:s.repeat(int count)
替换:s.replace(string old, string new)
去除空格:s.strip()
去除空格(两端): s.trim()

格式化:String.format()

/***** 判断 *****/
空串:isEmpty(), s == null, s.length() == 0, s.equals("")
包含:s.contains(string substr)
相等:==, s.equals(string s2), s.equalsIgnoreCase(string s2)
开头:startsWith(string prefix)
结尾:endsWith()
类型:s instanceof String

/***** 转换 *****/
大写:s.toUpperCase()
小写:s.toLowerCase()

字符串转数字:Integer.parseInt(string s)
数字转字符串:Integer.toString(int num), String.valueOf(int num), "" + num

字符串转数组:s.split(string regex)
数组转字符串:String.join(string exp, ...elems)

字符串转字节数组:s.toCharArray(), s.getBytes()
字节数组转字符串:new String(char[] chars)
// 字符串遍历
for(int i = 0; i < s.length(); i++) {
    System.out.println(s.charAt(i));
}

for (char c : s.toCharArray()) {
    System.out.println(c);
}
equals() & ==
// equals():覆盖则比较内容
// == : 基本数据类型比较值;引用数据类型比较内存地址
String name = "coulson";
String name2 = new String("coulson");

System.out.println(name == name2);       // fasle
System.out.println(name.equals(name2));  // true
@转换
String => chars: `s.toCharArray()`
String => Bytes: s.getBytes()
String => Array: s.split()/str.substring()

Array => String: `Arrays.toString()`
chars => String: new String(chars)

int => String: `String.valueOf(num)`、Integer.toString(num)、"" + num
String => int: `Integer.parseInt(s)`

@判断数据类型
str `instanceof` String

StringBuilder & StringBuffer

TIP

字符串构造器(减少耗时,节约空间)

  • String: 少量字符串操作,每次新建对象
  • StringBuilder:单线程, 非线程安全
  • StringBuffer: 多线程,线程安全 synchronized 运行速度:StringBuilder > StringBuffer > String

初始化

StringBulider sb = new StringBulider();
StringBulider bf = new StringBuffer();

StringBulider sb = new StringBulider("hello world");

增删改查

// StringBuild Api:
初始化:new StringBuild(string s), new StringBuffer(string s);

长度:length()
输出:toString()

增:append(e)
插:insert(i, e)
删:delete(int start, int end)
改:replace(int start, int end, string s)

字符:charAt(int i)
索引:indexOf(e)
反转:reverse()

链式编程

s.append(str1).append(str2).append(str3);

转换

String => StringBuilder:

StringBuilder s = new StringBuilder(str)

StringBuilder => String

s.toString();
//字符串反转
return new StringBuilder(str).reverse().toString();

数组

ArrayListHashMapHashSet
长度lengthsize()size()size()
add()put()add()
remove()remove()
arr[i]get()get()
arr[i] = v
fill(v)
set()
包含contains()containsKey()
containsValue()
排序Arrays.sort(arr)Collections.sort(list)

Array

数组是一种存储同一类型值的集合

WARNING

数组长度不能更改,需要经常扩展数组大小时,应该使用数组列表-List

长度为 0 的数组与 null 并不相同

创建数组

int[]   arr = new int[length];
int[]   arr = {1, 3, 5, 7, 9};
int[][] arr = {{1,2,3}, {4,5,6}};

数组遍历

for(int i = 0; i < nums.length; i++) {
    System.out.println(nums[i])
}

for(int v : nums) {
    System.out.println(v)
}

API

// 长度
arr.length

// 输出数组
System.out.println(Arrays.toString(arr)); // [1, 3, 5, 7]
System.out.println(arr);     //arr数组对象的内存地址:[I@7a81197d
System.out.println(arr[0]);  //数据的默认值:0

// 排序(从低到高)
Arrays.sort(arr)
// Array -> List
Arrays.asList(arr)

// 打印二维数组元素
Arrays.deepToString(arr)
Arrays.copeOf(arr, arr.length)

// 二分查找:在有序数组a中查找v值,如果有则返回下标,否则返回负数值; ***为数据类型
binarySeach(arr, start, end, *** v)

WARNING

索引越界: ArrayIndexOutOfBoundsException 空指针异常:NullPointerException

ArrayList & LinkedList

TIP

ArrayList<T>: 数组列表 (存储和访问数据更快)
LikedList<String>:链表 (操作数据更快:插入/删除/修改)
// LikedList存储内存地址(或链接到)跟随它的元素,因为每个元素都包含一个链接到邻近的元素。
import java.until.ArrayList;
ArrayList<Integer> list = new ArrayList<>();
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(nums));
ArrayList<Integer> list = new ArrayList<>(List.of(new Integer[]{ 1, 2, 3 }));

增:add(T e), Collections.addAll(list, ...nums)
删:remove(int index), clear()
改:set(i, e)

查:
System.out.println(list.get(i));
System.out.println(list.size());
System.out.println(list.contains(e));
System.out.println(list);




import java.until.LikedList;
LikedList<String>  list = new LikedList<>();
add(i, e)
example
// 初始化方式
List<Integer> list = new ArrayList<>(Arrays.asList(nums));
List<Integer> ints = new ArrayList<>(List.of(new Integer[]{ 1, 2, 3 }));

增:
    a)add(e):末尾新增
    b)add(i, e):中间插入
    c)Collections.addAll(list, 4, 5);
删:
    a)remove(i):删除单个索引元素
    b)clear():  删除所有元素
查:
    a)size():长度
    b)get(i):索引值
    c)System.out.println(list):所有值
    d)contains(e):判断包含
改:set(i, e)
排序:
    a)升序:Collections.sort(list)
    b)降序:Collections.reverse(list)
    c)随机:Collections.shuffle(list)
最值:
    最大值:Collections.max(list)
    最小值:Collections.min(list)
example2
public class ArrayListDemo {
    public static void IntegerList() {
        Integer[] nums = {2, 5, 3, 1, 7};
        List<Integer> list = new ArrayList<>(Arrays.asList(nums));
        // 增
        list.add(9);                    // 末尾增加
        list.add(1, 2);   // 中间插入
        // 删
        list.remove(0);
        // list.clear();
        // 改
        list.set(1, 8);
        // 查
        System.out.println(list.size());    // 长度
        System.out.println(list);           // 所有值
        System.out.println(list.contains(4));
        System.out.println(list.get(1));    // 索引值

        // 排序
        Collections.sort(list);
        Collections.reverse(list);
        Collections.shuffle(list);
    }
}

HashMap

TIP

<Key, value>: 哈希表 (存储键 : 值)
import java.util.HashMap;

HashMap<Integer, Integer> map = new HashMap<>();



增:put(k, v)   // 已存在的键key新增会替换原来的value,相当于修改操作
删:remove(k), clear()
查:size()get(k)
判断:containsKey(k), containsValue(v)
查所有键值对:System.out.println(map)

// 遍历
for (int k = 0; k < map.size(); k++) {
    System.out.printf("key: %d, value: %d \n", k, map.get(k));
}
example
import java.util.HashMap;

public class hashmap {
    public static void main(String[] args) {
        HashMap<Integer, Integer> map = new HashMap<>();
        map.put(0, 1);
        map.put(1, 3);
        map.put(2, 5);
        map.put(3, 7);

        map.remove(3);

        map.put(2, 7);

        System.out.println(map);
        System.out.println(map.get(3));
        System.out.println(map.size());
        System.out.println(map.containsKey(2));
        System.out.println(map.containsValue(5));

        for (int k = 0; k < map.size(); k++) {
            System.out.printf("key: %d, value: %d \n", k, map.get(k));
        }
    }
}

HashSet

import java.util.HashSet;

HashSet<Integer> set = new HashSet<>();



增:add(e)
删:remove(e), clear()
判断:set.contains(e)
查:size(), System.out.println(set)

Collections

import java.util.Collections;

Collections.sort(list);            //升序
Collections.reverse(List list);    //降序
Collections.shuffle(List list);    //随机排序
Collections.max(Collection c);
Collections.min(Collection c);

Collections.addAll(list, 1, 2)

Iterator

import java.util.Iterator;

Iterator<T> it = list.iterator();
while (it.hasNext) {
    T value = it.next()
    System.out.println(value);
}

hasNext()
next()
remove()

Java 类与对象

OOP :

  • encapsulation(封装:隐藏数据)
  • inheritance(继承:继承另一个类的全部"non-private"属性[变量和方法]用 extends)
  • polymorphism(多态性)
  • abstraction.(抽象性)

封装

//1、封装
public class Person {
    private int age;
    public void setAge(int age) {
        if(age>0) {
            this.age = age;
        }
    }
}
// 标准类的封装
package Test;

public class Student {
    // 成员变量(用private来保护数据)
    private int id;
    private String name;
    private int age;
    private String address;
    // private final String name = "Coulson";  (常量, 没有setName方法)
    // private static String name = "Coulson"; (静态成员变量, 可以被所有成员共享.)
    // privete static final age = 20;

    // Constructors: 无参构造方法
    public Student() {...}

    // 带参构造方法
    public Student(String id, String name, String age, String address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    // 成员方法
    //Getters & Setters: 封装的基本构建块(private属性)
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }

    //Behaviour: what student does
    //static修饰methods时:内置函数(只能调用有static修饰的属性)
    public static void show() {
        System.out.println(name)
    }
}
// 封装类对象的调用
public static void main(String[] args) {
    Student s1 = new Student();    //*创建对象: 类名 对象名 = new 类名();
    s1.setId("001");
    s1.setName("coulson");
    s1.setAge("24");
    s1.setAddress("China");
    System.out.println(s1.getId()+"\t\t"+s1.getName()+"\t\t"+s1.getAge()+"\t\t"+s1.getAddress());

    Student s2 = new Student(id:"001", name:"coulson", age:"24", address:"China");
    System.out.println(s1.getId()+"\t\t"+s1.getName()+"\t\t"+s1.getAge()+"\t\t"+s1.getAddress());

}

修饰符

访问权限修饰符
* public: 对所有类可见
* protected: 同一包内的类和所有子类可见
* default: 同一包内可见
* private: 当前类可见

static静态修饰符
1. static修饰变量:
被类的所有对象共享(static静态修饰实例变量时,调用新建对象成员属性时,其他新建对象成员属性值也会改变;
也可通过类名来调用 (既可以通过新建对象名访问)
2. static修饰方法:只能访问static成员变量


final(最终态):
a.final变量:   常量,不可再次赋值, 没有setter方法.
b.final方法:   不可被重写.
c.final修饰类: 不可被继承.
d.final修饰新建引用对象类型,是指引用对象内存地址值不可变,但地址内的内容仍是可变的。)

* 返回值类型void : 表示该方法不会返回任何值(若return后面有值, 则需修改)
* 方法名 main:  main是主方法的默认方法名

继承

class Dog extends Animal {
    //some code
}

/**
 * private属性和方法不可继承
 * super.var可访问超类私有属性
 */
* 适用场景:当需要使用有相同的成员属性和相同的成员方法时使用类的继承
* 示例:苹果和水果,猫(子类)和动物(父类), 学生和人,不支持同等类如猫狗之间用继承
* 继承特点:只支持单继承,不支持多继承(Son extends Father,Mother),但可支持多层继承(class son entends Father{}; class Father extends Granddad{})
class 子类名 extends/implement 父类名 {}

* 继承类成员变量和成员方法的使用
super.***:超类引用(父类)
this.***:  代表所在类的对象引用(本类)

super() //调用父类成员数据和方法,会额外开辟内存空间

* 不同调用变量方法
var
this.variable
uper.variable

* 父类方法重写:
@Override    //注解:检查重写方法有无写错
public ...(...){}    //private私有方法不可重写;子类访问方法权限不能更低(public > default >private)

父类
void func(){}        //父类有public子类也得有
子类
public void func() {}    //去掉public也可以

包 package(文件夹)

一、用包对类分类管理
* 包的定义:package 包名;
* 建包:
手动:新建文件夹com,再建立文件夹MyTest,再把class类文件放在包最内层
自动:javac -d.className.java (CMD命令行执行)



二、导包:
假设需要用其他包中的文件
1. 方法1
package 本类所在包;
...
包路径.类名 对象名 = new 包路径.类名();
2. 方法2
package 本类所在包;
import 包路径.类名;
...
对象名 = new 类名();

多态

//3、多态性(多个子类继承同一个超类,子类重写/重载超类方法)
class Animal {
    public void makeSound(){
        System.out.printIn("grr...");
    }
}


class Cat extends Animal {
    public void makeSound(){        //Method overriding方法重写--运行时的多态性
        System.out. println("Meow");
    }
}


class Dog extends Animal {
    @Override //判断方法重写是否有误
    public void makeSound(){
        System.out. printIn("woof");
    }
}


public static void main(String[]args){
    Animal dog = new Dog();
    Animal cat = new Cat();
}
/**子类重写超类的方法规则:
* 相同的返回值类型和参数
* 访问级别无法比重写的方法更为严格的访问级别(例如:如果超类方法声明为public,子类的重写方法既不能是private,也不能是protected)
* final or static 声明的方法无法重写
* 无法继承的方法无法重写
* 构造方法不能被重写
*/


/**
* 方法重写: 相同的方法名、返回值类型和参数
* 方法重载:相同的方法名,但返回值和参数类型不同 --编译时的多态性
*
*/

使用前提:

  • 继承关系
  • 方法重写
  • 父类引用指向多个子类对象
原始:Cat c = new Cat();
多态:Animal a = new Cat();
        Animal a;
        a = new Animal();
        a = new Cat();
多态成员访问特点:
        * 成员变量:编译看左边,执行看左边
        * 成员方法:编译看左边(父类有这个方法则通过),执行看右边 (成员方法有重写,而成员变量没有)
优点:定义方法时,使用父类型作为参数,将来具体使用时用子类参与操作,减少代码。
弊端:不能访问子类的特有功能方法。

转型(->):使用子类的特有功能
    Animal a = new Cat();
    a.eat();
    //a.playGame(); //子类特有,而父类没有,则报错
    解决方法:
    Animal a = new Cat();
    Cat c = (Cat)a;    //强制转换成子类
    c.eat();
    c.playGame();
转型(向上:子->):父类强转为子类后,其他子类需要使用父类
    Animal a = new Cat();
    Cat c = (Cat)a;
    a = new Dog();  //Animal d = new Dog();  新建对象d,占用内存;而a是原地更改对象
    //ClassCastException 类转换异常
    //Cat cc = (Cat) a;  //a指向Dog内存地址,而cc指向猫。java中赋值是引用内存地址。

抽象

//4、抽象abstraction
abstract class Animal {
    int legs = 0;
    public int age;
    abstract void makeSound();
    public abstract int showAge();    // method() {...}
}


class Cat extends Animal {
    public void makeSound(){
        System.out.println("Meow");
    }
}


class Dog extends Animal {
    public int showAge() {
        return age;
    }
}




/**抽象规则:
*  抽象类
*  抽象方法
* 不能使用实例化(无法创建该类型的对象)
* 使用一个抽象类,必须从另一个类继承
*/

接口

//Ⅰ接口Interfaces(完全抽象的类)


interface Animal {
    public void eat();
    public void makeSound();
}


class Cat implements Animal {
    public void makeSound(){
        System.out. printIn("Meow");
    }
    public void eat(){
        System.out. printIn("omnomnom");
    }
}


//一个类可以继承一个超类,但可以实现多个接口
//泛型接口
public class Student{
    public <T> void show(T t){
        ...
    }
}

//泛型通配符
List<? extend Number> list = new ArayList<Integer>();
List<? super Number> list = new ArrayList<Object>();

//多个可变参数构造方法
public static int sum(int... a) {
   ...
}
public static String join(String sep,String... s){...}

类的转换

//向上转换upcasting
Animal cat = new Cat();


//向下转换Downcasting(超类对象强制转换为它的子类)
Animal cat = new Cat();
((Cat) cat).makeSound();

类中类的几种形式

1.匿名类(Anonymous Classes)

class Machine {
    public void start {
        System.out.println("Starting...");
    }
    public static void main(String[] args) {
        Machine m1 = new Machine() {
            @Override         //@Override注释:显示地提示在重写代码
            public void start() {
                System.out.println("Wooooo");
            }
        };
        m1.start();    //"Wooooo"
         Machine m2 = new Machine();
         m2.start();     //"Starting"
    }
}

2.内部类/嵌套类:private class

class Robot {
    int id;
    Robot(int i) {
        id = i;
        Brain b = new Brain();
        b.think();

    }

    private class Brain {    //可以访问所有外部类地成员变量和方法,但它不能被任何外部类访问-> 人工智能
        public void think() {
            System.out.println(id + " is thinking");
        }
    }
}

3.组合类

public class ...{ }
class ...{}

HashCode( ) & Equals( )

import java.util.Objects;

class Animal {
    String name;
    Animal(String n) {
        name = n;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Animal)) return false;
        Animal animal = (Animal) o;
        return Objects.equals(name, animal.name);
    }

/*
 *  精简写法
    @Override
    public boolean equals(Object o) {
        return ((Animal) o).name == this.name;
    }
*/
    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}

class Myclass {
    public static void main(String[] args) {
        Animal a1 = new Animal("Robby");
        Animal a2 = new Animal("Robby");
        System.out.println(a1 == a2);       //false,判断引用对象内存地址是否相等
        System.out.println(a1.equals(a2));  //true,判断引用对象内容是否相等
    }
}

枚举 Enum(定义常量的集合,使用 switch 检查)

//枚举Enums (定义常量的集合,使用switch检查)
enum Color {
    RED, BLUE, GREEN;
}
class EnumsDemo {
    public static void main(String[] args) {
        Color color = Color.RED;
        String str = switch (color) {
            case BLUE -> "1";
            case GREEN -> "2";
            case RED -> "3";
        };
        System.out.println(str);    //"3"
    }
}

Exceptions, Lists, Thread & Files

异常处理 (为防止线程终止,需要用处理器捕获异常)

try - catch - finally

// 捕获异常try - catch - finally
try {
    //some code
} catch (Exception e) {
    //some code to handle errors
} catch (IOException e) {
    ...
} finally {    //可选
    ...
}

throws

//throws主动抛出异常
int div(int a, int b) throws ArithmeticException {
    if(b == 0){
        throw new ArithmeticException("Division by Zero");    //多个异常用逗号隔开
    } else {
        return a/b;
    }
}

assert(测试)

* 断言: assert(如果condition为false则执行exception)
assert condition : exception;
// 需要主动启动断言(默认是禁止)
java -ea: ...
java -enablessertions ...

Swing 图形界面设计

格式:*** ... = new ...();

JFrame
JPanel
JDialog(对话框)
JMenuBar-JMenu-JmenuItem(菜单栏)
JPopupMenu(右键菜单)
ButtonGroup-JRadioButtonMenuItem
JTextField(单行文本)
JPasswordField
JTextArea(多行文本)
JLabel(标签)
JList<String>(列表框)
JComboBox<String>(下拉选择框)
JCheckBox(复选框)
JButton(按钮)
JRaidoButton(单选按钮)
JTable
1.新建窗口
2.新建组件,设置组件方法和监听行为
3.新建面板,并添加组件至面板
4.添加面板至窗口,并显示窗口
import javax.swing.*;


public class Main {
    public static void main(String[] args) {
        // 1.新建窗口,设置点击"关闭"退出程序
                    JFrame jf = new JFrame("窗口测试");
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        // 2.新建面板并布局;新建组件,设置组件事件响应,并添加组件至面板
        JPanel panel = new JPanel(...);
        JButton button = new JButton();
        button01.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ...  //showNewWindow(jf);
            }
        });
        panel.add(button);

        // 3.添加面板至窗口,并显示窗体
        jf.add(panel);
        jf.setVisible(true);
    }

    public static void showNewWindow(JFrame relativeWindow) {
    JFrame newJf = new JFrame(String title);
    ...
    newJf.setVisable(True);
    }
}
* @JFrame
import javax.swing.*;

基本必备方法:
// 1.创建窗口
JFrame jf = new JFrame(String title);
// 2.“关闭”响应
jf.setDefaultCloseOperation(JFram.EXIT_ON_CLOSE);
/**
* (WindowConstants)=>(JFrame)
* 参考值:
* EXIT_ON_CLOSE  //结束进程
* HIDE_ON_CLOSE  //隐藏窗口(不会结束进程),再次调用setVisible(true)将再次显示
* DISPOSE_ON_CLOSE //销毁,如果所有窗口都销毁则自动结束进程
* DO_NOTHING_ON_CLOSE  //不执行任何操作, 点击关闭无效
*/
// 3.显示窗口(放置末尾)
jf.setVisible(true);


others:
// 位置居中(实际并未真正实现居中--> 如何调整窗口位置?)
jf.setLocationRelativeTo(null);
jf.setBounds(x,y,width,height);
// 图标
jf.setIconImage(Image image);
// 大小
jf.setSize(int width, int height);
// 是否可缩放
jf.setResizeable(boolean);
// 布局
jf.pack();
// 置顶显示
jf.setAlwaysOnTop(boolean);
// 是否可见
jf.setVisible(boolean);
// 销毁
jf.dispose();
// 是否处于显示状态
jf.isShowing();
// 添加面板
jf.add(panel, BorderLayout.SOUTH);
jf.setContentPane(panel);
* @JMenuBar
// 菜单栏
JMenuBar menubar = new JMenuBar();
// 一级菜单
JMenu fileMenu = new JMenu(String menuName);
menubar.add(fileMenu);
// 一级菜单的子菜单
JMenuItem copy = new JMenuItem(String subMenuName, new ImageIcon(String imagePath));
fileMenu.add(copy);
fileMenu.addSeparator(); //分割线
* @Dialog(对话框)
showMessageDialog    //WARNING_MESSAGE, 无输出
showConfirmDialog    //YES_NO_CANCEL_OPTION
showInputDialog      //PLAIN_MESSAGE
showOptionDialog    //ERROR_MESSAGE

JButton button = new JButton(String title);
button.addActionListener(new ActionListener() {
    @override
    public void actionPerdormed(ActionEvent e) {
        Object[] options = new Object[] {..., ..., ...};
        JOptionPane.show***Dialog(
            if,
            String ...,
            String ...,
            JOptionPane.PLAIN_MESSAGE
        );
        System.out.println(...);
    }
});

@Button
@RadioButton
@JRadioButton
button01.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        JButton button01 = (JButton) e.getSource();
        System.out.println("正在播放");
    }
});

@CheckBox
checkBox.addChangeListener(new ChangeListener() {
    @Override
    public void stateChanged(ChangeEvent e) {
        JCheckBox checkBox = (JCheckBox) e.getSource();
        System.out.println(checkBox.getText()+" 是否选中: "+checkBox.isSelected());
    }
});
* setFocusPainted(false);

        JRadioButton radioButton01 = new JRadioButton("男", true);
        JRadioButton radioButton02 = new JRadioButton("女");
        radioButton01.setFocusPainted(false);
//        radioButton01.setContentAreaFilled(false);
        radioButton02.setFocusPainted(false);


        ButtonGroup buttonGroup = new ButtonGroup();
        buttonGroup.add(radioButton01);
        buttonGroup.add(radioButton02);


        JPanel panel = new JPanel();
        panel.add(radioButton01);
        panel.add(radioButton02);
        jf.add(panel);
@TextArea
//自动换行
setLinewrap(boolean);
setWrapStayleWord(boolean);

文件操作

  • read File
    • new Scanner(new File(pathname)) -- fp.colse()
    • new Scanner(new FileInputStream(filepath), StandardCharsets.UTF_8))
  • creat File
    • new Formatter(filepath)
  • write File
    • fp.format(str, arg1, ...) -- fp.close()
File.exists()
move()
read()
write()
size()
delete()
cope()
crateFile()
creatDirectory()
fp.getName()

读取文件

//方法一:colse()
import java.io.File;

try {
    File file = new File(filepath);
    Scanner sc = new Scanner(file);  //Scanner sc = new Scanner(new File(pathname));
    while (sc.hasNext()) {
        System.out.println(sc.next());
    }
    sc.close();
} catch (FileNotFoundException e) {
    System.out.println("error");
}
//方法二:try-with-resources 资源自动关闭
try (Scanner sc = new Scanner(new FileInputStream(filepath), StandardCharsets.UTF_8)) {
    while (sc.hasNext())
        System.out.println(sc.nextLine());
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

写入文件

/* Writting to File */
import java.util.Formatter;
...
try {
    //创建文件
    Formatter fp = new Formatter(filepath);
    //写入文件
    fp.format("%s %s %s", "1","John","Smith \r\n");    //1 John Smith
    fp.format("%s %s %s", "2","Amy","Brown");          //2 Amy Brown
    fp.close();
} catch (Exception e) {
    System.out.println("Error");
}
//如果文件已经存在,则覆盖

多线程

  • extends Thread
  • new ClassName()
  • implement Runnable
  • new Thread(new ClassName)

Runnable 接口(推荐)

/* Runable */
class classname implements Runable {
    @Override
    public void run() {
       //code
    }
}

class Main {
    public static void main(String[] args) {
        Thread t = new Thread(new  classname());
        t.start();

        try {
             Thread.sleep(1000);
        } catch (InterruptedException e) {
            //some code
        }
    }
}

Thread 继承(开销大,不推荐)

//1、Thread 继承(开销大,不推荐)
public class ThreadDemo extends Thread {
    public void run(){
        System.out.println("Hello");
    }
    public static void main(String[] args) {
        ThreadDemo t = new ThreadDemo();
        t.start();
    }
}


//2、Runnable 接口(推荐)
public class ThreadDemo implement Runnable {
    public void run(){
        System.out.println("Hello");
    }
    public static void main(String[] args) {
        Thread t = new Thread(new ThreadDemo);
        t.start();
    }
}


/**
* @执行时间计算
long start = System.currentTimeMillis();
...
long end = System.currentTimeMillis();
System.out.printf("执行时间%d ms\n", end-start);
*/


/**
* @sleep
try {
    Thread.sleep(1000);     //1000ms = 1s
} catch (InterruptedException e) {
    e.printStackTrace();
}
*/


//wait()

Thread.sleep()

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    //some code
}

System.currentTimeMillis()

/**
* @执行时间计算
long start = System.currentTimeMillis();
...
long end = System.currentTimeMillis();
System.out.printf("执行时间%d ms\n", end-start);
*/

//wait()

TIP

事后分析估算方法:

  • 可干预
  1. 算法采用的策略和方案
  2. 问题的输入规模
  • 不可干预
  1. 编译产生的代码质量
  2. 机器执行指令的速度

算法核心:

  • 执行时间(时间复杂度)
    • O(1) -- 两数之和
    • O(LogN) -- 二分查找
    • O(N) -- 循环:找出最大元素
    • N(logN) -- 分治思想:归并排序
    • O(N^2) -- 双循环:检查所有元素对
    • O(N^3) -- 三循环:检查所有三元组
    • O(2^N) -- 穷举查找:检查所有子集
    • ...
  • 内存消耗(现在内存都比较大,空间复杂度一般不要求。如果是做嵌入式开发,尤其是传感器上的内置程序,由于内存很小,一般为几 Kb,这时需要做空间复杂度分析了)
    • 基本数据类型内存消耗
      • byte (1)
      • short (2)
      • int (4)
      • long (8)
      • float (4)
      • double (8)
      • boolean (1)
      • char (2)
    • 新建对象内存消耗 new A() public class A { privete int a=1; } _ 整型成员变量 a 占用 4 个字节 _ 对象本身占用 16 字节
    • 引用:8 个字节 Date date = new Date(); //new date:创建对象消耗 8 个字节 //date:变量引用消耗 8 个字节
    • 一般内存的使用,如果不够 8 个字节,都会被自动填充为 8 个字节 :::

正则表达式

Pattern p = patterm.compile(arg)

Matcher m = p.matcher(str);
if(m.find()) {
    System.out.println(m.group());

TIP

其他语言中:\表示插入一个普通的反斜线""

Java 中

  1. 双斜线:\表示想要插入一个正则表达式的反斜线,其后的字符才具有意义. 比如"\d"表示匹配数字。
  2. 四斜线:\\表示插入"\"或""
  3. 单斜线:\n\t: 换行和制表符

大写字母则取反: \d: 数字[0-9] \w: 词字符[a-zA-Z0-9] \s: 空白符(" "、\t、\n、\f、Enter) \e: 转义符

(): 整体看待 [abc]: 其中任一字符(同于 a|b|c) {m,n}: 至少 n 次,且不少过 m 次("{n}":恰好 n 次;"{n,}":至少 n 次)

? : (0|1)个,有 1 个或没有;非贪婪匹配(匹配数量:尽可能匹配所需的最少字符数) . : 任意数量字符

  • :[1, +∞) 有/至少 1 次
  • :范围([a-zA-Z0-9])
  • : [0, +∞) 或许有 \: java 正则匹配符或反斜线""

X|Y: X 或 Y "(-|\+)?" => [0,1]个"+"/"-" ^XY: 都非(单个非"[^x]Y") XY : X 和 Y

FAQ

for, while, do...while 的区别

1) for & while loops 先判断再输出
     do...while 先输出再判断,所以至少会输出一次!
2) for loops 变量在循环语句内,变量不可再次使用;
3) 而while loops 变量在循环语句外,变量还可再次使用。

Packages

Math

最大值:Math.max()
最小值:Math.min()

下浮:Math.floor()
上浮:Math.ceil()

绝对值:Math.abs()
幂:Math.pow()
四舍五入:Math.round()
随机数:Math.random()

生成随机数:
[0, 10]: Math.round(Math.random() * 10)
[0, 10): (int)Math.floor(Math.random() * 10)
/**
 * Math Api:
 * Math.min()
 * Math.max()
 *
 * Math.floor()
 * Math.ceil()
 *
 * Math.abs()
 * Math.round()
 * Math.random()
 *
 * Math.pow()
 */

public class math {
    public static void main(String[] args) {
        System.out.println(Math.min(3, 5));     // 3
        System.out.println(Math.max(3, 5));     // 5

        System.out.println(Math.floor(3.4));    // 3.0
        System.out.println(Math.ceil(3.4));     // 4.0

        System.out.println(Math.abs(- 3.2));    // 3.2
        System.out.println(Math.round(3.62));   // 4
        //Math.random() 生成随机数
        System.out.println(Math.round(Math.random() * 10)); // [0, 10]
        System.out.println((int)Math.floor(Math.random() * 10)); // [0, 10)

        int num = (int) (Math.random() * 10);
        System.out.println(num);

        //new Random() 生成随机数
        Random r = new Random();
        int i = r.nextInt(10);
        System.out.println(i);

        System.out.println(Math.pow(2, 3)); // 8.0
    }
}

Date

日期格式化

import java.text.SimpleDateFormat;
import java.util.Date;

public class date {
    public static void main(String[] args) {
        System.out.println(dateToString());
    }

    public static String dateToString() {
        Date date = new Date();
        // System.out.println(date);   // Fri Nov 25 23:54:47 CST 2022
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        // System.out.println(dateFormat.format(date));    // 2022-11-25 11:55:56

        return dateFormat.format(date);
    }
}

休眠

try {
    Thread.sleep(3000);
} catch (InterruptedException e) {
    e.printStackTrace();
}

执行时间计算

long start = System.currentTimeMillis();
// function
long end = System.currentTimeMillis();
long diff = end - start;
System.out.println("执行时间: " + diff);

正则 regex

Matcher m = Pattern.compile(regex).matcher(s);

while (m.find())  {
    System.out.println(m.group());
}
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class regex {
    public static void main(String[] args) {
        String s = "hello, my name is Bob, I'm 20 yeas old, the date is 2021-10-12. you can send message to bob@gmail.com";

        Pattern p = Pattern.compile("\\d+");
        Matcher m = p.matcher(s);
        while (m.find())  {
            System.out.println(m.group());
        }
    }
}

/*
20
2021
10
12
 */