Java语法

Java语法

基本细节

小tip:
1.编程重在理解模仿,而不在于记忆
2.代码的执行是单线程的,即一行一行的执行
3.String比较特殊,是因为String里的值是不被修改的,如果修改String里的值会再开辟一段空间地址存新的值,原来的数值是不变的
4.引用传递本质上也是值传递,只不过引用传递传的是地址,而地址也是一个值
5.java中没有指针的概念

var
// var类似于C++的auto

输出时自动转类型
// 转类型时自动小范围转大范围(也可以大转小)
System.out.println('A' + 2); //输出67

Java语法中的除是向零取整
System.out.println(10/20); //输出0

浮点数判相等
if(Math.abs(x - y) < 1e-8)

输出
System.out.printf("%04d",5); //输出0005,不足4位前面补零
System.out.printf("%4d",5); //输出   5,占4位不补零
System.out.printf("%-4d",5); //输出5   ,占4位不补零,空格在后

输入输出流(效率高)
// 效率较高,输入输出规模较大时使用。注意需要抛异常。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;

public class Main {
    public static void main(String[] args) throws Exception {// 要异常抛出
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        String[] str = br.readLine().split(" ");
        int x = Integer.parseInt(str[0]);
        int y = Integer.parseInt(str[1]);
        bw.write(Integer.toString(x + y));
        bw.flush();// 手动刷新缓存
    }
}

数组定义
// java中的数组是可以重新赋值的,其实就是一个变量,跟普通变量没有区别。
int[] a = {0, 1, 2};
a = new int[10];
// 还可以这样赋值初始化
int[] s = new int[]{y, x};
// java中没有指针的概念
// java中的数组如果不初始化是不能用的,是一个空数组null。必须先赋初值后使用变量也是一样的,如果不赋初值也不能用,所以java不容易出错。
int[] a = new int[10]; // 定义长度为10的数组a,初始值为0
int[] a = new int[10], b; // 定义两个数组,b为空数组
String[] str = new String[10]; // 定义长度为10的String类型的数组,初始值为null
// char的初始值是'\0'

数组的范围遍历
for(数据类型 变量名:数组名)
{
    这个变量名就代表数组中的每一项元素了,直接使用变量名进行操作
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int[][] a = {
            {0, 1, 2, 3},
            {4, 5, 6, 7},
            {8, 9, 10, 11},
        };

        for (int[] row: a) {  // 范围遍历
            for (int x: row)  // 范围遍历
                System.out.printf("%d ", x);
            System.out.println();
        }
    }
}
/*	输出:
        0 1 2 3 
        4 5 6 7 
        8 9 10 11 
*/

函数重载
// 函数重载是指:在同一个类中存在多个函数,函数名称相同但参数列表不同。
// 编译器会根据实参的类型选择最匹配的函数来执行。

import java.util.Scanner;

public class Main {
    private static int max(int a, int b) {
        System.out.println("int max");
        if (a > b) return a;
        return b;
    }

    private static double max(double a, double b) {
        System.out.println("double max");
        if (a > b) return a;
        return b;
    }

    public static void main(String[] args) {
        // 根据传入的参数类型找到最匹配的函数执行
        System.out.println(max(3, 4)); // 调用int max()
        System.out.println(max(3.0, 4.0)); // 调用double max()
        System.out.println(max(3.0, 4)); // 调用double max()
    }
}

引用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xWJjHqhL-1673971054940)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20221120042022255.png)]

// 八大基本数据类型和String类型等采用值传递。
// 除String以外的数据类型的对象,例如数组、StringBuilder等采用引用传递。
// 将实参的引用(地址)传给形参,通过引用找到变量的真正地址,然后对地址中的值修改。所以此时对形参的修改会影响实参的初始值。

// 引用StringBuilder
public class Main{
    private static void f1(StringBuilder str){
        str = new StringBuilder("HelloWorld");
    }
    
    private static void f2(StringBuilder str){
        str.append("HelloWorld");
    }
    
    public static void main(String[] args){
        StringBuilder sb = new StringBuilder("");
        f1(sb);
        System.out.println(sb); // 输出空,实参未改变
        f2(sb);
        System.out.println(sb);// 输出HelloWorld,实参变量
    }
}

String类

初始化
String a = "lyt";
String b = a; // 存储到相同的地址
// 因为java中String是一个对象,它的变量之间赋值会指向同一段内存,同一个变量
String d = "My age is " + 18;  // int会被隐式转化成字符串"18"
String str = String format("My age is %d.", 19); // 格式化字符串,类似于C++中的printf
// 将字符串转化为对应基本数据类型
String money_str = "123.25";
String money_st = "123";
double money = Double.parseDouble(money_str); // String转double
int money_i = Integer.parseInt(money_st); // String转int
// 基本数据类型转化为对应字符串
方式一:利用拼接空字符串
int money=123;
String money_str = "" + money;
方式二:用对象定义基本数据类型,这样就可以利用API toString()Integer money = 123;
String money_str=money.toString();

注意事项
1.// String是只读变量,不能修改: C++中的string类是可以修改的,而java中的String类是不能修改的,每次修改完之后就会变成一个全新的变量.
2.//访问String中的字符:C++中访问字符串跟访问数组是一样的,而java中只能通过API来访问
String str = "Hello World";
for (int i = 0; i < str.length(); i ++ ) { //数组的length是不加括号的,而字符串的length是需要加括号的
	System.out.print(str.charAt(i)); // 只能读取,不能写入
}
Stringlength()
String[] 用length

StringBuilder、StringBuffer
// String不能被修改,如果打算修改字符串,可以使用StringBuilder和StringBuffer。
// StringBuffer线程安全,速度较慢;StringBuilder线程不安全,速度较快。

StringBuilder sb = new StringBuilder("Hello ");  // 初始化
sb.append("World");  // 拼接字符串
System.out.println(sb);

for (int i = 0; i < sb.length(); i ++ ) {
    // 修改字符,把位置i上的字符修改成ASCII码的下一位
    sb.setCharAt(i, (char)(sb.charAt(i) + 1));  // 读取和写入字符
}
System.out.println(sb);

// 常用API: reverse():翻转字符串

面向过程与面向对象

面向过程:强调的是功能行为,以函数为最小单位,考虑怎么做

面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做


属性,局部变量在内存中加载的位置
属性:堆空间(static)
局部变量:栈空间(static)    
static:方法区

类与对象

类定义一种全新的数据类型,包含一组变量和函数;对象是类这种类型对应的实例。例如在一间教室中,可以将Student定义成类,表示“学生”这个抽象的概念。那么每个同学就是Student类的一个对象(实例)。


源文件声明规则
  • 一个源文件中只能有一个public类。
  • 一个源文件可以有多个非public类。
  • 源文件的名称应该和public类的类名保持一致。
  • 每个源文件中,先写package语句,再写import语句,最后定义类。

类的定义
  • public: 所有对象均可以访问
  • private: 只有本类内部可以访问
  • protected:同一个包或者子类中可以访问
  • 不添加修饰符:在同一个包中可以访问
  • 静态(带static修饰符)成员变量/函数与普通成员变量/函数的区别:
    • 所有static成员变量/函数在类中只有一份,被所有类的对象共享;
    • 所有普通成员变量/函数在类的每个对象中都有独立的一份;
    • 静态函数中只能调用静态函数/变量;普通函数中既可以调用普通函数/变量,也可以调用静态函数/变量。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l6Nyxc9P-1673971054941)(F:\图片\Saved Pictures\QQ图片20221122190409.jpg)]

public class Main{
    class Student{
        public static int x = -1;
        public int y = -1;
    }
    
    public static void main(String[] args){
        Student stu1 = new Student(), stu2 = new Student(),stu3 = new Student();
        //公有变量应该用类名调用,而不是对象名,虽然也不会报错但最好用类名调用
        // stu1.x = 2;
        Student.x = 2;
        stu1.y = 2;
        System.out.printf("%d %d %d\n", stu1.x, stu2.x, stu3.x); // 输出2 2 2
        System.out.printf("%d %d %d\n", stu1.y, stu2.y, stu3.y); // 输出2 -1 -1
    }
}

类的构造函数

Point.java

package org.lyt.point;

public 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);
    }
}

Main.java

package org.lyt;

import org.lyt.point.Point;

public class Main {
    public static void main(String[] args){
        Point point = new Point(3, 4);
        System.out.println(point.toString());
        // 数组调用
        Point[] points = {new Point(5, 4)};
        System.out.println(points[0].toString());
    }
}


类的继承

每个类只能继承一个类。

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() {// Point类中 x,y 是private不能直接访问
        return String.format("(%d, %d, %s)", super.getX(), super.getY(), this.color);
    }

类的多态
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());
    }
}

接口

interfaceclass类似。主要用来定义类中所需包含的函数。

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

一个类要实现一个接口的话,必须实现接口里面定义的所有函数。

接口的定义
// 接口中不添加修饰符时,默认为public。
interface Role {
    public void greet();
    public void move();
    public int getSpeed();
}

接口的继承
// 每个接口可以继承多个接口
interface Hero extends Role,Boold { // 要继承几个往后面加几个接口且用","隔开
    public void attack();
}

接口的实现
// 每个类可以实现多个接口
// 一个类要实现一个接口的话,必须实现接口里面定义的所有函数。
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;
    }
}

接口的多态
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(); 
        }
    }
}
/*
	输出:
		Hi!
		Hi!!!
*/

常用函数

判断字符串是否相等
s.equals("string"); 
// 写工程时,若字符串s为空会报异常,可以写成这样"string".equals(s);
//java用equals方法比较的是字符串的内容是否相同,先判断地址是否相等,相等返回true;比较类型是否一样,不一样,返回false。

整数转字符串
// toString(): 返回表示 Integer 值的 String 对象.
// Integer.toString(int i): 返回表示指定 int 的 String 对象.
public class Test{
    public static void main(String args[]){
        Integer x = 5;
        System.out.println(x.toString());  
        System.out.println(Integer.toString(12)); 
    }
}

四舍五入的方法
Math.ceil(double a); //向上舍入,将数值向上舍入为最为接近的整数,返回值是double类型

Math.floor(double a); //向下舍入,将数值向下舍入为最为接近的整数,返回值是double类型

Math.round(float a); //标准舍入,将数值四舍五入为最为接近的整数,返回值是int类型

Math.round(double a); //标准舍入,将数值四舍五入为最为接近的整数,返回值是long类型

Java读入char的方法
// 要读取char,我们使用next().charAt(0)。next()函数返回输入中的下一个标记/字符作为字符串,并且charAt(0)函数返回该字符串中的第一个字符。
Scanner sc = new Scanner(System.in);
char ch = sc.next().charAt(0);	

匿名函数
// 一维数组
Integer[] q = new Integer[n]; // Integer是对象类型的整数
Arrays.sort(q, (x, y) -> { // 加个匿名函数
    return x - y; // 从小到大, 若x-y>0返回正数就是把x排在y的后面, x-y<0就是排在y的前面
    return y - x; // 从大到小, 若y-x>0返回正数就是把x排在y的后面, 反之亦然
});
// 二维数组
// 二维数组中的每一个一维数组本身就是一个对象,所以他不需要用Integer
Arrays.sort(q, (x,y) ->{ //加一个匿名函数
	return x[0]-y[0];
} );

字符串转成char数组
String str = "Hella World";
char[] cs = str.toCharArray();
System.out.println(cs);
for(char c : cs)
    System.out.print(c);

"\\s+"表示匹配任意多个空白字符
1.// 正则表达式中\s匹配任何空白字符
// 而"\s+"则表示匹配任意多个上面的字符,再加个反斜杠转义就是"\\s+"
String str = sc.nextLine();
System.out.println(str.replaceAll("\\s+"," ")); // "\s+"表示匹配任意多个空白字符
    
2.// 补充
// [\s]表示,只要出现空白就匹配
// [\S]表示,非空白就匹配

Arrays.sort()实现逆序
Integer []num = {1,2,3};
Arrays.sort(num, Collections.reverseOrder()); // 比较器
Arrays.sort(num, ( Integer a, Integer b) -> { // 加匿名函数
	return b-a;
});

位运算
lowbit(x) = x & -x;
x >> k & 1; // 第k位是0还是1
// 位运算的优先级比加减的低
1 + 2 ^ 3 + 4 相当于 (1 + 2) ^ (3 + 4)

不断读入数据直至文件尾 != EOF
Scanner sc = new Scanner(System.in);
// C++的while(cin.hasNext()){}
// while(scanf("%d",&x) != EOF){}
while(sc.hasNext()){
    
}

常用API

Arrays
属性length:返回数组长度,注意不加小括号
Arrays.sort(int[] array):数组排序 // 可以三个参数Arrays.sort(array,l,r);给区间排序[l,r)
Arrays.fill(int[] array, int val):填充数组(只能初始化一维数组)
Arrays.toString(int[] array):将数组转化为字符串(返回值类型String)
Arrays.deepToString():将多维数组转化为字符串,输出[x,y,...]这样的模式
Arrays.equals(int[] a, int[] b):判断两个数组是否相等(返回值类型boolean)
Arrays.binarySearch(int[] a, int key):对排序后的数组进行二分法检索指定的值(int),没找到返回负数
数组不可变长
int sum = Arrays.stream(array).sum(); // 快速数组求和
使用Arrays需要import java.util.Arrays 

String
length():返回长度
split(String regex):分割字符串 
indexOf(char c)indexOf(String str)lastIndexOf(char c)lastIndexOf(String str):查找,找不到返回-1
equals():判断两个字符串是否相等,注意不能直接用== // a.equals(b)
compareTo():判断两个字符串的字典序大小,负数表示小于,0表示相等,正数表示大于 // a.compareTo(b)
startsWith():判断是否以某个前缀开头 // s.startsWith("string")
endsWith():判断是否以某个后缀结尾
trim():去掉首尾的空白字符 // s.trim()
toLowerCase():全部用小写字符
toUpperCase():全部用大写字符
replace(char oldChar, char newChar):替换字符
replace(String oldRegex, String newRegex):替换字符串
substring(int beginIndex, int endIndex):返回[beginIndex, endIndex)中的子串,若写一个参数则返回这个参数位置到末尾,若输入的参数大于字符串长度会报错,C++substr(idx,length)下标,长度
toCharArray():将字符串转化成字符数组

异常处理

一个运行是异常,没有捕获的话,代码会直接中止,告诉我们异常是什么东西。

捕获异常
// 可嵌套
// 运行效率很慢,不建议放到循环里
try{
	...
} catch (... | ...) {
	...
} catch (...) {
    ...
} finally {
    ... // 这里的代码无论如何都会执行
}

样例

import java.util.Scanner;

public class Main {

    private static void foo() {
        int[] array = new int[5];
        for (int i = 0; i < 5; i ++ )
            array[i] = i;

        Scanner sc = new Scanner(System.in);
        int k = sc.nextInt();
        int x = sc.nextInt();

        try {
            array[k] /= x;
        } catch (ArithmeticException e) {
            System.out.println("除零错误!");
            e.printStackTrace();
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组越界!");
            e.printStackTrace();
        } finally {
            for (int i = 0; i < 5; i ++ ) {
                System.out.println(array[i]);
            }
        }
    }

    public static void main(String[] args) {
        foo();
    }
}

抛出异常

throw: 在函数内抛出一个异常。
throws:在函数定义时抛出一些可能的异常。

检查型异常必须被捕获或者抛出。

import java.io.IOException;
import java.util.Scanner;

public class Main {

    private static void foo() throws IOException, NoSuchFieldException {
        Scanner sc = new Scanner(System.in);
        int x = sc.nextInt();
        if (x == 1)
            throw new IOException("找不到文件!!!");
        else
            throw new NoSuchFieldException("自定义异常");
    }

    public static void main(String[] args) {
        try {
            foo();
        } catch (IOException e) {
            System.out.println("IOException!");
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            System.out.println("NoSuchFieldException!");
            e.printStackTrace();
        }
    }
}

try-with-resources

JDK7 之后,Java新增的try-with-resource语法糖来打开资源,并且可以在语句执行完毕后确保每个资源都被自动关闭.
try 用于声明和实例化资源,catch 用于处理关闭资源时可能引发的所有异常.

import java.io.*;

public class Main {

    public static void main(String[] args) {
        String line;
        try (
                BufferedReader br = new BufferedReader(new FileReader("input.txt"));
                BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"));
        ) {
            while ((line = br.readLine()) != null) {
                System.out.println("Line => " + line);
                bw.write("copy: " + line + "\n");
            }
            bw.flush();
        } catch (IOException e) {
            System.out.println("IOException in try block =>" + e.getMessage());
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值