JAVA_快速入门部分

JAVA SE快速入门

class
method方法
field域,指一种属性,可以是类变量、方法变量、参数等
instance实例

注意区分变量和实例

Person ming = new Person();

Person ming是定义Person类型的变量ming,而new Person()是创建Person实例。

简介

​ Java代码本质是一种字节码,类似于抽象的CPU指令,针对不同平台编写虚拟机,通过虚拟机加在字节码执行,实现多平台开发。

  • JAVA SE:标准版
  • JAVA EE:企业版(加入大量API和库)
  • JAVA ME:迷你版(针对嵌入式的瘦身版)(SE的标准库在ME上无法使用)

先学习Java SE,掌握Java语言本身、Java核心开发技术以及Java标准库的使用
如果继续学习Java EE,那么Spring框架、数据库开发、分布式架构就是需要学习的;

特性:简单性、面向对象、可移植性、高性能、分布式(URL)、动态性(反射)、多线程、安全性、健壮性

JDK和JRE:
JDK:依赖包(JAVA Developement Kit)从源码到字节码
JRE:运行环境(Java Runtime Environment)类似虚拟机
JDK包括JRE,另外还提供了编译器和调试器等开发工具
JSR:接口规范要求(Java Specification Request),给JAVA加功能时先穿件一个JSR规范,定义好接口,一个JSR发布时应该同时发布示例代码。
JVM:JAVA虚拟机

运行过程:
​ 源代码被Java编译器转化成字节码(Byte Code),然后通过JVM这个虚拟机,字节码就能在各个平台上运行。
Image result for java bytecode and jvm

hello.java

public class Hello{
    //以类(class)为结构展开,大小写敏感,public表示类是公开的。一个Java源码只能定义一个Public类型的class
	public static void main(String[] args){
        // 定义一个main方法,其中void是返回类型,String[]是参数类型,参数名为args,public和static修饰方法(公开且静态)
		System.out.println("Hello World!");
        // java使用‘;’结尾,缩进一般为4个空格
	}
}

注:Java程序总是从main方法开始执行

保存文件时,文件名必须为Hello.java,即要和类名保持一致

在这里插入图片描述

两种运行方法:

  1. java Hello.java直接运行源码(仅用于单个不依赖第三方库的Java源码!)
  2. javac Hello.java ——> 产生Hello.class; java Hello ——>执行类

小结

  1. 一个Java源码只能定义一个public类型的class,并且class名称和文件名要完全一致;
  2. 使用javac可以将.java源码编译成.class字节码;
  3. 使用java可以运行一个已编译的Java程序,参数是类名。

基础知识

程序基本结构

public class Hello{	//访问修饰符 类关键词 类名
	public static void main(String[] args){	//访问修饰符 修饰符 返回类型 方法名(参数类型 参数名)
		System.out.println("Hello World!");
	}
}

以hello为例,JAVA是面向对象语言,一个程序的基本单位是class
Public是访问修饰符,如果没有这个修饰类也能编译,但不能从命令行执行
类中可以定义若干的方法(Method),如main
static表示静态方法,也是修饰符
JAVA入口程序规定的方法必须是静态方法,方法名必须是main,括号内的参数必须是String数组。

​ 注释:采用“/** **/” 跨行注释时,放于类和方法定义处,可以自动创建文档

变量

基本类型变量

先定义后使用,定义是可以给初始值(默认初始0),定义阶段要指明变量类型。可以重复赋值

public class Main{
	public static void main(String[] args){
        int n = 100;
        int x = n+100;
        System.out.println("x = "+x);// 这里的+值的是输出第二个内容的意思。即括号内改成 "n="+"x",则输出"n = x"
	}
}

变量类型:(4+2+1+1)

  • 整数类型:byte(1字节),short(2字节),int(4字节),long(8字节)
  • 浮点数类型:float(4字节),double(8字节)
  • 字符类型:char(2字节)(可以表示中文,即unicode)
  • 布尔类型:boolean(通常存作4字节)

不同进制表示同一个数是完全相同的 15=0xf0b1111

引用类型变量

类似指针

eg : String s = “hello”

定义变量时加上final修饰符,变量成为常量 final double PI = 3.14

var关键字:

var sb = new StringBuilder();
//编译器会推断出sb是StringBuilder,使得以下两句等价
StringBuilder sb = new StringBuilder();
var sb = new StringBuilder();

变量作用范围:
​ 在语句块中定义的变量,它有一个作用域,就是从定义处开始,到语句块结束。

小结

  • Java提供了两种变量类型:基本类型和引用类型
  • 基本类型包括整型,浮点型,布尔型,字符型。
  • 变量可重新赋值,等号是赋值语句,不是数学意义的等号。
  • 常量在初始化后不可重新赋值,使用常量便于理解程序意图

整数运算

/ :整除
% :取余

注:数值溢出的时候不会报错,但会返回奇怪的结果(采用long类型避免溢出)

++n表示先加1再引用n,n++表示先引用n再加1(不建议用于常规运算)

左移处理(<<)等同于十进制2*

对负数右移(>>),最高位的1不限,即仍然为负数(但>>>则为无符号右移,可以改变正负)

与或非:&、|、 -

异或: ^

int和short运算时,输出为int(运算前short被转为int)

强制转型可能报错,int转short,则丢失2个高位字节

public class Main{
	public static void main(String[] args){
        int i1 = 1234567
        short s1 = (short) i1;	//-10617
        System.out.println(s1);
        int i2 = 12345678;
        short s2 = (short) i2;	//24910
        System.out.println(s2)
    }
}

小结

  • 整数运算的结果永远是精确的;
  • 运算结果会自动提升;
  • 可以强制转型,但超出范围的强制转型会得到错误的结果;
  • 应该选择合适范围的整型(intlong),没有必要为了节省内存而使用byteshort进行整数运算。

浮点数运算

​ 只能做数值运算,不能做位运算和移位运算。

浮点数存在无法精确表示的问题:二进制无法表示某些小数,只能趋近(如0.1)
​ 故比较浮点数大小采用减法进行判断

// 比较x和y是否相等,先计算其差的绝对值:
double r = Math.abs(x - y);
// 再判断绝对值是否足够小:
if (r < 0.00001) {
} else {
}

参与运算整数去兼容浮点数

浮点数可以做0的除法

double d1 = 0.0 / 0; // NaN
double d2 = 1.0 / 0; // Infinity
double d3 = -1.0 / 0; // -Infinity

浮点到整形要进行四舍五入可以通过+0.5实现。

布尔运算

优先级:

  • !
  • >>=<<=
  • ==!=
  • &&
  • ||

短路运算:如果一个布尔运算的表达式能提前确定结果,则后续的计算不再执行,直接返回结果。

eg:boolean b = 5 < 3;
boolean result = b && (5 / 0 > 0); // b已经false不用计算后续,否则 5 / 0 将报错

三元计算:

b ? x : y	// b为true则运行x,否则y,返回选中的操作

小结

  • 与运算和或运算是短路运算;
  • 三元运算b ? x : y后面的类型必须相同,三元运算也是“短路运算”,只计算xy

字符和字符串

中文英文都占用2字节,显示unicode编码只需要将char复制给int

转义符

可以用\u+unicode编码表示一个字符

在需要表示 “ 字符时,使用 \” 表示,\被称为转义字符(\ \ 则表示\)

  • \" 表示字符"
  • \' 表示字符'
  • \\ 表示字符\
  • \n 表示换行符
  • \r 表示回车符
  • \t 表示Tab
  • \u#### 表示一个Unicode编码的字符

可以通过 + 连接任意字符串和其他数据类型,以便字符串处理。

可以通过char(Unicode)转为字符

多行字符串:

​ 采用"""..."""表示多行字符串如(共同空格将被去掉):

public class Main {
    public static void main(String[] args) {
        String s = """		// 开始
                     users
                   WHERE id > 100
                   ORDER BY name DESC
                   """;		// 结束
        System.out.println(s); //包括5行,因为DESC后相当于还有一个\n
    }
}

字符串是不可变的引用变量——变的只会是变量的指向

public class Main {
    public static void main(String[] args){
        String s = "hello";
        System.out.println(s);
        s = "world";
        System.out.println(s);
    }
}

在这里插入图片描述

public class Main {
    public static void main(String[] args) {
        String s = "hello";
        String t = s;
        s = "world";
        System.out.println(t); // 输出"hello"
    }
}

创建引用变量可以指向一个空值(null),注意null不等于"",后者是空字符串。

小结

  • Java的字符类型char是基本类型,字符串类型String是引用类型;
  • 基本类型的变量是“持有”某个数值,引用类型的变量是“指向”某个对象;
  • 引用类型的变量可以是空值null
  • 要区分空值null和空字符串""

数组类型

      int[] ns = new int[5]		//其中int为数组元素类型,5为数组大小
      int[] ns = new int[] { 68, 79, 91, 85, 62 }; //直接初始化元素就不必定义数组大小

数组是引用类型,数组一旦创建后,大小就不可改变。

可以用ns.length获取数组大小(ns为数组名)

如果用ArrayList即动态数组初始化时就不用限制数组大小

字符串数组:

​ 如果数组元素不是基本类型,而是一个引用类型如字符串,对于String[]类型的数组变量names,它实际上包含3个元素,但每个元素都指向某个字符串对象。对其中元素赋新值时效果如下图:
在这里插入图片描述

小结

  • 数组是同一数据类型的集合,数组一旦创建后,大小就不可变;
  • 可以通过索引访问数组元素,但索引超出范围将报错;
  • 数组元素可以是值类型(如int)或引用类型(如String),但数组本身是引用类型;

流程控制

输入输出

输出

​ System.out.println() //换行

​ System.out.print() //不换行

​ System.out.printf("%.4f\n", d); // 显示4位小数3.1416,格式化显示

占位符说明
%d格式化输出整数
%x格式化输出十六进制整数
%f格式化输出浮点数
%e格式化输出科学计数法表示的浮点数
%s格式化字符串

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Formatter.html#syntax

输入

System.in 即标准输入流,通过Scanner类简化in的后续操作

scanner.nextLine() 读取用户输入的字符串

scanner.nextInt() 读取用户输入的整数

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sanner = new Scanner(System.in);// 创建Scanner对象
        System.out.print("Input your name: "); // 打印提示
        String name = scanner.nextLine(); // 读取一行输入并获取字符串
        System.out.print("Input your age: "); // 打印提示
        int age = scanner.nextInt(); // 读取一行输入并获取整数
        System.out.printf("Hi, %s, you are %d\n", name, age); // 格式化输出
    }
}

小结

Java提供的输出包括:System.out.println() / print() / printf(),其中printf()可以格式化输出;

Java提供Scanner对象来方便输入,读取对应的类型可以使用:scanner.nextLine() / nextInt() / nextDouble()

课后题:

import java.util.Scanner;
// 输入两次成绩,返回保留两位小数的提升百分比
public class Main {
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        System.out.println("Input your last score:");
        int score1 = scanner.nextInt();
        System.out.println("Input your this score:");
        int score2 = scanner.nextInt();
        double percent = 100.0*(score2-score1)/score1;
        System.out.printf("improve:%.2f%%",percent);
    }
}

if判断

if语句块只有一行语句时,可以省略花括号{};但仍要换行。

样例:

        if (n >= 90) {
            System.out.println("优秀");
        } else if (n >= 60) {
            System.out.println("及格了");
        } else {
            System.out.println("挂科了");
        }

注意边界条件。

注:判断浮点数的 == 时,通常采用减法后的某个数 < 某个临界值来判断。

当两个引用类型的变量指向不同对象但内容相同时,用==判断的结果也为false,应当使用equals() 方法
​ 如:s1.equals(s2)

小结

  • if ... else可以做条件判断,else是可选的;
  • 不推荐省略花括号{}
  • 多个if ... else串联要特别注意判断顺序;
  • 要注意if的边界条件;
  • 要注意浮点数判断相等不能直接用==运算符;
  • 引用类型判断内容相等要使用equals(),注意避免NullPointerException

switch多重选择

switch (option) {
        case 1:	//case判定字符串时是判断内容,不是地址
            System.out.println("Selected 1");
            break;
        case 2:
            System.out.println("Selected 2");
            break;
        default:
            System.out.println("Not selected");
            break;
        }

用break跳出选择,如果没有break将在选择到的语句后一直执行直到出现break

用default表示没有匹配到任何case时执行

新版java中采用 ->{} 连接匹配语句避免穿透执行。并且可以直接返回值

public class Main {
    public static void main(String[] args) {
        String fruit = "apple";
        int opt = switch (fruit) {
            case "apple" -> 1;
            case "pear", "mango" -> 2;
            default -> 0;
        }; 	// 注意赋值语句要以;结束
        System.out.println("opt = " + opt);
    }
}
yield

大多数时候,在switch表达式内部,我们会返回简单的值。但如果需要复杂的语句,我们也可以写很多语句,放到{...}里,然后,yield返回一个值作为switch语句的返回值

public class Main {
    public static void main(String[] args) {
        String fruit = "orange";
        int opt = switch (fruit) {
            case "apple" -> 1;
            case "pear", "mango" -> 2;
            default -> {
                int code = fruit.hashCode();
                yield code;	 // switch语句返回值
            }
        };
        System.out.println("opt = " + opt);
    }
}

小结

  • switch语句可以做多重选择,然后执行匹配的case语句后续代码;
  • switch的计算结果必须是整型、字符串或枚举类型;
  • 注意千万不要漏写break,建议打开fall-through警告;
  • 总是写上default,建议打开missing default警告;
  • 从Java 14开始,switch语句正式升级为表达式,不再需要break,并且允许使用yield返回值。

while循环

先判断是否成立,然后循环

while( 条件 ){ 语句 }

do while

另外还有do while,区别在于,do while先进行一次循环主体再进行判定

do{语句}while(条件);

小结

  • while循环先判断循环条件是否满足,再执行循环语句;
  • while循环可能一次都不执行;
  • 编写循环时要注意循环条件,并避免死循环。
  • do while循环先执行循环,再判断条件;do while循环会至少执行一次。

for 循环

与python基本一致

for (初始条件; 循环检测条件; 循环后更新计数器) {}

注,在循环条件内尽量不要修改计数器以避免逻辑错误

for each

常用于遍历数组

    int[] ns = { 1, 4, 9, 16, 25 };
    for (int n : ns) {	//不需计数器,直接是数组元素
        System.out.println(n);
    }

小结

  • for循环通过计数器可以实现复杂循环;
  • for each循环可以直接遍历数组的每个元素;
  • 最佳实践:计数器变量定义在for循环内部,循环体内部不修改计数器;

break和continue

break跳出当前这层循环

continue会结束本次循环,进入下次循环

小结

  • break语句可以跳出当前循环;
  • break语句通常配合if,在满足条件时提前结束整个循环;
  • break语句总是跳出最近的一层循环;
  • continue语句可以提前结束本次循环;
  • continue语句通常配合if,在满足条件时提前结束本次循环

数组操作

遍历

通过 for循环

打印数组时需要注意,System.out.println(ns) 将打印ns数组的引用地址

采用for循环或者Arrays.toString()

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] ns = { 1, 1, 2, 3, 5, 8 };
        System.out.println(Arrays.toString(ns));
    }
}

小结

  • 遍历数组可以使用for循环,for循环可以访问数组索引,for each循环直接迭代每个数组元素,但无法获取索引;
  • 使用Arrays.toString()可以快速获取数组内容。

排序

冒泡、插入和快速

冒泡排序

每次循环最大的数交换到末尾

功能函数:Arrays.sort(ns) ——> 在ns上直接做修改,即数组的指向内容已经变化

小结

  • 常用的排序算法有冒泡排序、插入排序和快速排序等;
  • 冒泡排序使用两层for循环实现排序;
  • 交换两个变量的值需要借助一个临时变量。
  • 可以直接使用Java标准库提供的Arrays.sort()进行排序;
  • 对数组排序会直接修改数组本身。

多维数组

二维数组:

int[][] ns = {
            { 1, 2, 3, 4 },
            { 5, 6, 7, 8 },
            { 9, 10, 11, 12 }
        };

在这里插入图片描述

加入定义普通数组,并把ns[0]赋值给它,则它获得第一个数组

二维数组的每个数组元素的长度并不要求相同,例如,可以这么定义ns数组:

int[][] ns = {
    { 1, 2, 3, 4 },
    { 5, 6 },
    { 7, 8, 9 }
};

要打印可以用两层for循环,或者使用Java标准库Arrays.deepToString()

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[][] ns = {
            { 1, 2, 3, 4 },
            { 5, 6, 7, 8 },
            { 9, 10, 11, 12 }
        };
        System.out.println(Arrays.deepToString(ns));
    }
}

三维数组:

在这里插入图片描述

小结

  • 二维数组就是数组的数组,三维数组就是二维数组的数组;
  • 多维数组的每个数组元素长度都不要求相同;
  • 打印多维数组可以使用Arrays.deepToString()
  • 最常见的多维数组是二维数组,访问二维数组的一个元素使用array[row][col]

命令行参数

java的命令入口是main方法,而main方法可以接受一个命令行参数,是一个String[],这个命令行参数由JVM接收用户输入并传给main。

可以利用接收到的命令行参数,根据不同的参数执行不同的代码。例如,实现一个-version参数,打印程序版本号:

public class Main {
    public static void main(String[] args) {
        for (String arg : args) {
            if ("-version".equals(arg)) {
                System.out.println("v 1.0");
                break;
            }
        }
    }
}

在命令行执行,需要再传递一个参数

javac Main.java
java Main -version
v 1.0		//输出

小结

  • 命令行参数类型是String[]数组;
  • 命令行参数由JVM接收用户输入并传给main方法;
  • 如何解析命令行参数需要由程序自己实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值