【acwing之springboot框架课(一)】java语法基础

1.简单介绍

java和c#一样都是纯面向对象的语言
所有函数和对象都要写到类里面,入口是main函数
java没有指针,只有引用

2. 基本概念

JDK、JRE、JVM的关系:
在这里插入图片描述
JDK:Java Development Kit,Java开发工具包(JRE配上一些常用的编译调试工具)
JRE: Java Runtime Environment,Java运行环境(JVM再配上一些常用的库、包)
JVM:Java Virtual Machine,Java虚拟机
java代码运行后不会像c一样直接变成.exe可执行文件(机器码),而要通过java字节码,需要用java解释器来运行
JDK包含JRE,JRE包含JVM(java解释器)
JDK版本选择
目前JDK1.8(也叫JDK8,注意不是JDK18)用得最多
Java代码的编译运行流程
将Java源码编译成Java字节码。
使用JVM将Java字节码转化成机器码。
JVM作用:跨平台、内存管理、安全。
JSE、JEE、JME的区别
JSE: Java Standard Edition,标准版
JEE:Java Enterprise Edition,企业版
JME: Java Mirco Edition,移动版
Spring是JEE的轻量级替代品(JSE上开发的)
SpringBoot是Spring + 自动化配置

3.java基础语法
3.1 变量、运算符、输入与输出
类似于C#,Java的所有变量和函数都要定义在class中。
3.1.1 内置数据类型
在这里插入图片描述
1.2D双精度
3.1.2 常量
使用final修饰:

final int N = 110;

当我们试图修改由final修饰的值,会报错

3.1.3 类型转化
显示转化:int x = (int)'A';(高转低)
隐式转化:double x = 12, y = 4 * 3.3;(低转高)
补int x = Integer.parseInt(br.readLine()); //字符串转整型

3.1.4 表达式
与C++、Python3类似:

int a = 1, b = 2, c = 3;
int x = (a + b) * c;
x ++;

3.1.5 输入
方式1,效率较低,输入规模较小时使用。

Scanner sc = new Scanner(System.in);
var sc = new Scanner(System.in); //上述也可以这样写,但是1.8版本不支持
String str = sc.next(); // 读入下一个字符串
int x = sc.nextInt(); // 读入下一个整数
float y = sc.nextFloat(); // 读入下一个单精度浮点数
double z = sc.nextDouble(); // 读入下一个双精度浮点数
String line = sc.nextLine(); // 读入下一行

方式2,效率较高,输入规模较大时使用。注意需要抛异常。

package com.hmy;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        System.out.println(str);
    }
}

3.1.6 输出
方式1,效率较低,输出规模较小时使用。

System.out.println(123);  // 输出整数 + 换行
System.out.println("Hello World");  // 输出字符串 + 换行
System.out.print(123);  // 输出整数
System.out.print("yxc\n");  // 输出字符串
System.out.printf("%04d %.2f\n", 4, 123.456D);  // 格式化输出,float与double都用%f输出

方式2,效率较高,输出规模较大时使用。注意需要抛异常。

package com.yxc;

import java.io.BufferedWriter;
import java.io.OutputStreamWriter;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        bw.write("Hello World\n");
        bw.flush();  // 需要手动刷新缓冲区
    }
}

3.2 判断语句
3.2.1 if-else语句
与C++、Python中类似。

例如:

package com.yxc;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int year = sc.nextInt();
        if (year % 100 == 0) {
            if (year % 400 == 0)
                System.out.printf("%d是闰年\n", year);
            else
                System.out.printf("%d不是闰年\n", year);
        } else {
            if (year % 4 == 0)
                System.out.printf("%d是闰年\n", year);
            else
                System.out.printf("%d不是闰年\n", year);
        }
    }
}

3.2.2 switch语句
与C++中类似。

package com.yxc;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int day = sc.nextInt();
        String name;
        switch (day) {
            case 1:
                name = "Monday";
                break;
            case 2:
                name = "Tuesday";
                break;
            case 3:
                name = "Wednesday";
                break;
            case 4:
                name = "Thursday";
                break;
            case 5:
                name = "Friday";
                break;
            case 6:
                name = "Saturday";
                break;
            case 7:
                name = "Sunday";
                break;
            default:
                name = "not valid";
        }
        System.out.println(name);
    }
}

c++,java都能用%s输出一个字符串,但是c++里面不能用%s来输出一个string,java可以
c++输出string:printf(“%s\n”,str.c_str());
3.2.3 逻辑运算符与条件表达式
与C++、Python类似。
例如:

package com.yxc;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int year = sc.nextInt();
        if (year % 100 != 0 && year % 4 == 0 || year % 400 == 0)
        // 必须得把!=0写出来,和c++不同
            System.out.printf("%d是闰年\n", year);
        else
            System.out.printf("%d不是闰年\n", year);
    }
}

3.3循环语句
3.3.1 while循环
与C++、Python类似,例如:

int i = 0;
while (i < 5) {
    System.out.println(i);
    i ++ ;
}

3.3.2 do while循环
与C++、Python类似,例如:

int i = 0;
do {
    System.out.println(i);
    i ++ ;
} while (i < 5);

do while语句与while语句非常相似。唯一的区别是,do while语句限制性循环体后检查条件。不管条件的值如何,我们都要至少执行一次循环。

3.3.3 for循环
与C++、Python类似,例如:

for (int i = 0; i < 5; i ++ ) {  // 普通循环
    System.out.println(i);
}

int[] a = {0, 1, 2, 3, 4};
for (int x: a) {  // forEach循环
    System.out.println(x);
}

String[] strs = {"aaa","bbb","ccc"};
for (String str : strs)
	System.out.println(str);

3.4 数组
Java中的数组与C++中的数组类似。

3.4.1 初始化
与C++类似。
初始化定长数组,长度可以是变量,可以在初始化时赋值。

int[] a = new int[5];  // 初始化长度为5的int数组,初始值为0
int[][] a = new int[5][]; //二维,其他依次类推
int n = 10;
float[] b = new float[n];  // 初始化长度为n的float数组,初始值为0.0F
char[] c = {'a', 'b', 'c'};  // 初始化长度为3的char数组,初始值为:'a', 'b', 'c'
char[] d = c;  // d与c地址相同,更改c中的元素,d中的元素也会改变(赋的是c的引用,类似于静态数组)
//c++里面可以用字符数组来表示字符串,比如char c[4] = "abc"; 但是java里面不行

初始化如果是new的,默认初始化为0;如果是字符串,默认初始化为空串

3.4.2 数组元素的读取与写入
与C++类似。

int[] a = new int[5];

for (int i = 0; i < 5; i++) {
    a[i] = i;
}
for (int i = 0; i < 5; i ++ ) {
    System.out.println(a[i] * a[i]);
}

3.4.3 多维数组
与C++类似。

int[][] a = new int[2][3];
a[1][2] = 1;
int[][] b = {
        {1, 2, 3},
        {4, 5, 6},
};
System.out.println(a[1][2]);
System.out.println(b[0][1]);
int[][] a = new int[2][3];
a[1][2] = 1;
System.out.println(Arrays.toString(a)); //只输出一维的地址
System.out.println(Arrays.deepToString(a)); //递归把每一个数都输出

3.4.4 常用API

属性length:返回数组长度,注意不加小括号
Arrays.sort():数组排序(正序)
eg: int[] a = {2,1,5,3,4}; Arrays.sort(a);
如果要倒序:(自定义,变量名不能重,且自定义函数不支持默认类型,最好用对象)
Integer[] a = {2,1,4,7,5}; Arrays.sort(a, (x, y) -> y - x); System.out.println(Arrays.toString(a));
Arrays.fill(int[] a, int val):填充数组
eg: Arrays.fill(a, 100);将数组a的值全部赋为100
Arrays.toString():将数组转化为字符串
Arrays.deepToString():将多维数组转化为字符串
数组不可变长
判断是否相等不能用两个等于号,因为比较的是两个地址,而要这样用:if(op.equals(“M”)),这样用其实也不好,应为op变量有可能为空,所以我们最好写为:if(“M”.equals(op))

3.5 字符串
3.5.1 String类
初始化:

String a = "Hello World";
String b = "My name is";
String x = b;  // 存储到了相同地址
// x,b的地址一样
System.out.println(b.hashcode());
System.out.println(x.hashcode());
String c = b + "yxc";  // String可以通过加号拼接
String d = "My age is " + 18;  // int会被隐式转化成字符串"18"
String str = String.format("My age is %d", 18);  // 格式化字符串,类似于C++中的sprintf,python里面“My age is %d %(18)”(算构造函数的重载)
String money_str = "123.45";
double money = Double.parseDouble(money_str);  // String转double
Integer.paseInt();
Float.parseFloat();
Long.parseFloat();

只读变量,不能修改,例如:

String a = "Hello ";
a += "World";  // 会构造一个新的字符串,hashcode值不同

访问String中的字符:

String str = "Hello World";
for (int i = 0; i < str.length(); i ++ ) {
    System.out.print(str.charAt(i)); //等价于c++里面的a[i]
     // 只能读取,不能写入
}

常用API:

length():返回长度
split(String regex):分割字符串(c ++ 里面没有)

        String a = "Hello World";
        String[] strs = a.split(" ");
        //split可以跟正则表达式
        String[] strs = a.split("[ ]+ ");
  String[] strs = a.split("\\s+ "); // \s可以匹配空格、tab    System.out.println(Arrays.toString(strs));

indexOf(char c)、indexOf(String str):查找,找不到返回-1

String a = "Hello World";
String[] strs = a.split(" ");
        System.out.println(a.indexOf('o')); //4
        System.out.println(a.indexOf("Wo")); //6

equals():判断两个字符串是否相等,注意不能直接用==
compareTo():判断两个字符串的字典序大小,负数表示小于,0表示相等,正数表示大于
startsWith():判断是否以某个前缀开头
endsWith():判断是否以某个后缀结尾
trim():去掉首尾的空白字符
toLowerCase():全部用小写字符
toUpperCase():全部用大写字符
replace(char oldChar, char newChar):替换字符
replace(String oldRegex, String newRegex):替换字符串
substring(int beginIndex, int endIndex):返回[beginIndex, endIndex)中的子串(c++里面第一个参数是起点,第二个是长度,java第一个参数是起点,第二个是终点的下一位,左闭右开)

3.5.2 StringBuilder、StringBuffer
String不能被修改,如果打算修改字符串,可以使用StringBuilder和StringBuffer。

StringBuffer线程安全,速度较慢;StringBuilder线程不安全,速度较快。
线程就类似于我们并行做两个事情

并发一般都是锁实现的,信号量也是锁实现。

多次发送同一接口,服务器端处理属于多线程吗
服务器端开了多发个

运行特别慢,因为每加一个就会创造一个新串,是n方级别。

public class ServiceDemo {
    public static void main(String[] args) throws IOException {
        String s = "";
        for(int i = 0; i < 100000; i ++)
                s += "a";
        System.out.println(s);
    }
}

优化后

public class ServiceDemo {
    public static void main(String[] args) throws IOException {
        StringBuffer sb = new StringBuffer("");
        for(int i = 0; i < 10000; i ++)
            sb.append("a");
        System.out.println(sb);
    }
}
StringBuilder sb = new StringBuilder("Hello ");  // 初始化
sb.append("World");  // 拼接字符串
System.out.println(sb);

for (int i = 0; i < sb.length(); i ++ ) {
    sb.setCharAt(i, (char)(sb.charAt(i) + 1));  // 读取和写入字符
}

System.out.println(sb);

常用API:

reverse():翻转字符串

3.6 函数
Java的所有变量和函数都要定义在类中。(python和c可以定义到类外面)

函数或变量前加static(函数绑定到类本身)表示静态对象,类似于全局变量。
静态对象属于class,而不属于class的具体实例。
静态函数、变量用类名来访问,普通函数、变量用具体实例访问
静态类似于图中的y,普通类似于x
在这里插入图片描述

class Point{
    private int x;
    private static int y;

    public int f(){
        return 0;
    }
    public static int g(){
        return 0;
    }
}
public class Main{
    public static void main(String[] args){
        Point a, b, c;
    }
}

静态函数中只能调用静态函数和静态变量。

示例:

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        System.out.println(max(3, 4));
        int[][] a = new int[3][4];
        fill(a, 3);
        System.out.println(Arrays.deepToString(a));

        int[][] b = getArray2d(2, 3, 5);
        System.out.println(Arrays.deepToString(b));
    }

    private static int max(int a, int b) {
        if (a > b) return a;
        return b;
    }

    private static void fill(int[][] a, int val) {
        for (int i = 0; i < a.length; i ++ )
            for (int j = 0; j < a[i].length; j ++ )
                a[i][j] = val;
    }

    private static int[][] getArray2d(int row, int col, int val) {
        int[][] a = new int[row][col];
        for (int i = 0; i < row; i ++ )
            for (int j = 0; j < col; j ++ )
                a[i][j] = val;
        return a;
    }
}

java里面我们想定义一个全局变量怎么办?
当然java不能定义全局变量,但是,我们可以定义一个类。

class Argument{
    public final static int x = 1;
    public final static int y = 1;

}

public class Main{
    public static void main(String[] args){
        System.out.println(Argument.x);
    }
}

3.7 类与接口
3.7.1 类
class与C++、Python类 似。

3.7.1.1 源文件声明规则
一个源文件中只能有一个public类。
一个源文件可以有多个非public类。
源文件的名称应该和public类的类名保持一致。
每个源文件中,先写package语句,再写import语句,最后定义类。
3.7.1.2 类的定义
public: 所有对象均可以访问
private: 只有自己可以访问,自己的子类也不能访问

class Point {
    private int x;
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public String toString() {
        return String.format("(%d, %d)", x, y);
    }
}

c++、java不能同时返回多个参数,python可以

不用static可以省内存
3.7.1.3 类的继承
每个类只能继承一个类。
super是父类的引用
把相同的功能放在同一个地方,不用重新写

class ColorPoint extends Point {
    private String color;

    public ColorPoint(int x, int y, String color) {
        super(x, y);
        this.color = color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String toString() {
        return String.format("(%d, %d, %s)", super.getX(), super.getY(), this.color);
    } 
}

3.7.1.4 类的多态
同一个类的同一个函数有不同行为

public class Main {
    public static void main(String[] args) {
        Point point = new Point(3, 4);
        Point colorPoint = new ColorPoint(1, 2, "red");

        // 多态,同一个类的实例,调用相同的函数,运行结果不同
        System.out.println(point.toString());
        System.out.println(colorPoint.toString());
    }
}

3.7.2 接口
interface与class类似。主要用来定义类中所需包含的函数。

接口也可以继承其他接口,一个类可以实现多个接口。

3.7.2.1 接口的定义
interface Role {
public void greet();
public void move();
public int getSpeed();
}
3.7.2.2 接口的继承
每个接口可以继承多个接口
以前不能放函数体,现在可以

interface Hero extends Role {
    public void attack();
}

3.7.2.3 接口的实现
每个类可以实现多个接口

class Zeus implements Hero {
    private final String name = "Zeus";
    public void attack() {
        System.out.println(name + ": Attack!");
    }

    public void greet() {
        System.out.println(name + ": Hi!");
    }

    public void move() {
        System.out.println(name + ": Move!");
    }

    public int getSpeed() {
        return 10;
    }
}

每个接口可以被多个接口继承

interface Role{
    public void greet();
    public void move();
    public int getSpeed();
}

interface Hero extends Role{
    public void attack();
}

interface Hii extends Role{
    public void sleep();
}

类是不能多继承的,如果能的话调用super()就不知道该指向谁了
3.7.2.4 接口的多态

class Athena implements Hero {
    private final String name = "Athena";
    public void attack() {
        System.out.println(name + ": Attack!");
    }

    public void greet() {
        System.out.println(name + ": Hi!");
    }

    public void move() {
        System.out.println(name + ": Move!");
    }

    public int getSpeed() {
        return 10;
    }
}

public class Main {
    public static void main(String[] args) {
        Hero[] heros = {new Zeus(), new Athena()};
        for (Hero hero: heros) {
            hero.greet();
        }
    }
}

3.7.3 泛型

类似于C++的template,Java的类和接口也可以定义泛型,即同一套函数可以作用于不同的对象类型。
泛型只能使用对象类型,不能使用基本变量类型。

import java.util.Stack;

public class Main{
    public static void main(String[] args) {
        Stack<Integer> stk = new Stack<Integer>();
    }
}

3.8 常用容器
3.8.1 List

接口:java.util.List<>。
实现
java.util.ArrayList<>:变长数组
java.util.LinkedList<>:双链表
函数
add():在末尾添加一个元素
clear():清空
size():返回长度
isEmpty():是否为空
get(i):获取第i个元素
set(i, val):将第i个元素设置为val

public class Main{
    public static void main(String[] args) {
        Stack<Integer> st = new Stack<Integer>();
		// 等于号前后类型相同可以写为:Stack<Integer> st = new Stack<>();
		
        list.add(1);
        list.add(2);

        System.out.println(list.get(1));
        System.out.println(list);

        list.set(0, 100);
        System.out.println(list);
        list.clear();
    }
}

3.8.2 栈
类:java.util.Stack<>

函数:

push():压入元素
pop():弹出栈顶元素,并返回栈顶元素
peek():返回栈顶元素
size():返回长度
empty():栈是否为空
clear():清空
3.8.3 队列
接口:java.util.Queue<>

实现:

java.util.LinkedList<>:双链表
java.util.PriorityQueue<>:优先队列(小根堆)
默认是小根堆,大根堆写法:new PriorityQueue<>(Collections.reverseOrder())
函数:

add():在队尾添加元素
remove():删除并返回队头
isEmpty():是否为空
size():返回长度
peek():返回队头
clear():清空
3.8.4 Set
接口:java.util.Set

实现:

  • java.util.HashSet:哈希表
  • java.util.TreeSet:平衡树

函数:

add():添加元素(如果添加重复的,会把重复的去掉)
contains():是否包含某个元素
remove():删除元素
size():返回元素数
isEmpty():是否为空
clear():清空

java.util.TreeSet多的函数:
ceiling(key):返回大于等于key的最小元素,不存在则返回null
floor(key):返回小于等于key的最大元素,不存在则返回null
c++里面
upper_bound: 大于key的最小值
lower_bound: 大于等于key的最小值
3.8.5 Map
接口:java.util.Map<K, V>

实现:

java.util.HashMap<K, V>:哈希表
java.util.TreeMap<K, V>:平衡树
函数:

put(key, value):添加关键字和其对应的值
get(key):返回关键字对应的值
containsKey(key):是否包含关键字
remove(key):删除关键字
size():返回元素数
isEmpty():是否为空
clear():清空
entrySet():获取Map中的所有对象的集合
Map.Entry<K, V>:Map中的对象类型
getKey():获取关键字
getValue():获取值
java.util.TreeMap<K, V>多的函数:

ceilingEntry(key):返回大于等于key的最小元素,不存在则返回null
floorEntry(key):返回小于等于key的最大元素,不存在则返回null
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
队列不好用数组实现,所以这儿会报错,如果要删除队头元素的话需要把后续数组都向前移动一位,效率比较低,所以我们这没有提供在这里插入图片描述 在这里插入图片描述
在这里插入图片描述
注: 以上内容大多来自y总的讲义
springboot框架课地址:https://www.acwing.com/activity/content/punch_the_clock/1877/

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值