java

36 阅读11分钟

注释:

单行://

多行:/* */

文档:/** */

关键字的字母全部小写

类(class)是java最基本的组成单元

字面量:数据在程序中的书写格式(整数、小数、字符串、字符、布尔、空)

eg: public class ValueDemo1{

public static void main(String [] args){
	System.out.println(666);
	System.out.println(-777);
	System.out.println("我是帅哥");
	System.out.println(true);
	System.out.println("null");	//null不可直接输出,必须以字符串的形式
	System.out.println('y');
}

}

特殊字符

\t 制表符

在打印的时候,把前面的字符串长度用空格补齐到8或8的整数倍。

eg:

public class ValueDemo1{

public static void main(String [] args){
	System.out.println("name"+'\t'+"xuan");
	System.out.println("age"+'\t'+"18");
}
    

}

变量:其值可能发生改变的量

变量的定义格式: 数据类型 变量名 = 数据值

eg: public class ValueDemo1{

public static void main(String [] args){
	int a=10;
	System.out.println(a);
}
    

}

注意事项:

·变量只能存一个值

·变量名不允许重复定义

·一条语句可以定义多个变量

·变量在使用之前一定要进行赋值

·变量的作用域范围

基本数据类型

整数(byte<-128—127>,short,int<10位数>,long<19位数>)

浮点数(float,double)

字符(char)

布尔(boolean)(true,false)

定义long类型的变量时,在数据值的后面加一个L作为后缀

eg:long n=9999999L;

定义float类型变量时,在数据值的后面加一个F作为后缀

eg:float f=10.1F;

double>float>long>int>short>byte

标识符:就是给类,方法,变量起的名字。

命名规则:

·由数字、字符、_和 $ 组成。

·不能以数字开头

·不能是关键字

·区分大小写

·小驼峰,大驼峰(见名知意)

键盘录入

java写好了一个类Scanner,这个类就可以接受键盘输入的数字。

步骤一:导包——Scanner这个类在哪

import java.util.Scanner(写在类前)

步骤二:创建对象——用Scanner这个类

Scanner sc = new Scanner(System.in) //sc可变f

步骤三:接收数据

int i = sc.nextInt();

eg:

import java.util.Scanner;

public class HelloWorld{

public static void main(String[] args){

    Scanner sc = new Scanner(System.in);

    int a=sc.nextInt();

    System.out.println(a);

}

}

java运算

整数参与运算结果只能得到整数,要想得到小数,必须有浮点数参与。

小数参与运算时,结果有可能不精确。

数字进行运算时,数据类型不一样不能运算,需要转成一样的,才能运算。

类型转换

隐式转换(自动类型提升):取值范围的数值->取值范围的数值

·取值范围小的和取值范围大的进行运算,小的会先提升为大的,再进行运算

·byte short char三种类型的数据在运算的时候,都**会先提升为int**,然后再进行运算

eg:int a = 10;
    
    double b = a;
    
    10->10.0

强制转换:取值范围大的数值->取值范围小的数值

如果把一个取值范围大的数值,赋值给取值范围小的变量,是不允许直接赋值的,如果一定要这么做就要加入强制转换。

格式:目标数据类型 变量名 = (目标数据类型)被强转的数据

eg:double a=12.3;
   int b=(int)a;
   
   int a=300;
   byte b=(byte)a;//报错(byte最大127)
   
   byte b1=10;
   byte b2=20;
   byte result=(byte)(b1+b2);//byte在参与运算时自动转换成了int

字符串的“+”操作

· 当“+”操作中出现字符串时,这个“+”是字符串连接符,而不是算术运算符了

 eg:"123"+123->"123123"
 

·连续进行“+”操作时,从左到右逐个执行

 eg:1+2+"33"->"333"
     
    1+2+"abc"+2+1->"3abc21"
    
    
eg:
public class ArithmeticoperatorDemo1 {
    public static void main(String[] args) {
        Scanner sc =new Scanner(System.in);
        int a=sc.nextInt();
        System.out.println("个位:"+a%10+"\n十位:"+a/10%10+"\n百位:"+a/100);
    }
}

字符的“+”操作

当 字符+字符,字符+数字时,会把字符通过ASCII码表查询到对应的数字再进行计算。(a:97,A:65

赋值运算符

+=,-=,*=,/=,%= 底层都隐藏了一个强制类型转换。

eg:
short s=1;
s+=1;//等同于s=s+1,short在运算时会提升为int,这里相当于把int变成了short,大变小本应该
进行强制类型转换(s=(short)(s+1))才行,此处没有报错是因为底层隐藏了一个强制类型转换。

逻辑运算符

&,|,^(相同为false,不同为true),!(取反),&&(短路与),||(短路或).

短路逻辑运算符:如果左边就能确定整个表达式的结果了,右边不执行。

三元运算符: 关系表达式?表达式1 :表达式2;

eg:
int max=a>b ? a:b;
·首先计算关系表达式的值,如果为true,表达式1的值就是运算结果,如果值为false,表达式2的值就是运算结果。

运算符优先级 “()”优先于所有。

原码、反码、补码

原码:十进制数据的二进制表现形式,最左边是符号位,0为正,1为负。

利用原码对正数进行计算是不会有问题的,但如果是负数计算,结果就出错,实际运算的结果和我们预期的结果是相反的。

反码:为了解决原码不能计算负数的问题而出现的。

正数的补码反码是其本身,负数的反码是符号位保持不变,其余位取反。

用反码在进行负数运算时,如果结果不跨0,是没有任何问题的,但是如果结果跨0,跟实际结果的结果会有1的偏差,因为0有两种表示。

补码:正数的补码是其本身,负数的补码是在其反码的基础上+1。

0只有一种表示,解决了反码负数计算时跨0的问题。

并且多记录一个值-128。

计算机中的存储和计算都还是以补码的形式进行的。

逻辑与 &逻辑或|(计算数字,不同于上面的&,|),左移<< (向左移动,低位补0),右移>>(向右移动,高位补0或1,补还是补1看原来的数字,原来的数是正数就补0,负数就补1),右移一次相当于除2,右移两次相当于除4。无符号右移>>>(向右移动,高位补0)。

switch格式

switch(表达式){
    case1:
        语句体1break;
    case2:
        语句体2break;
    ………
    default:
        语句体n+1;
        break;
}

case后面的值只能是字面量,不能是变量

case给出的值不允许重复。

default可以省略,语法不会有问题,但不建议省略。

default不一定是写在最下面。

每个case后的break必须写,否则case穿透(从匹配上的case进入后,依次执行每个case后面的语句体)。

switch新特性(简化写法)(无break)

int num=1;
switch(num){
    case 1 -> {
        System.out.println("一");//若大括号里只有一行代码,大括号也可省略
    }
    case 2 -> {
        System.out.println("二");
    }
    case 3 -> {
        System.out.println("三");
    }
    default -> {
        System.out.println("没有选项");
    }
}

使用场景:

if的第三种格式:一般用于对范围的判断。

switch:把有限个数据一一列举出来,让我们任选其一。

case穿透用法:

public class ArithmeticoperatorDemo1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int week=sc.nextInt();
        switch(week){
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
                System.out.println("工作日");
                break;
            case 6:
            case 7:
                System.out.println("周末");
                break;
        }
    }
}

public class ArithmeticoperatorDemo1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int week = sc.nextInt();
        switch (week) {
            case 1, 2, 3, 4, 5:
                System.out.println("工作日");
                break;
            case 6, 7:
                System.out.println("周末");
                break;
            default:
                System.out.println("无该选项");
        }
    }
}

public class ArithmeticoperatorDemo1 {
   public static void main(String[] args) {
       Scanner sc = new Scanner(System.in);
       int week = sc.nextInt();
       switch (week) {
           case 1, 2, 3, 4, 5-> System.out.println("工作日");
           case 6, 7-> System.out.println("周末");
           default-> System.out.println("没有该选项");
       }
   }
}

判断回文数

思路:反转数字与原来做比较

public class ArithmeticoperatorDemo1 {
    public static int get_rev(int x){
        int rev=0;//666
        while(x!=0){
            int tem=x%10;
            x/=10;
            rev=rev*10+tem;
        }
        System.out.println(rev);
        return rev;
    }
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int x=sc.nextInt();
        if(get_rev(x)==x)
            System.out.println("true\n");
        else{
            System.out.println("false\n");
        }
    }
}

求两个数相除得到的的商和余数(不能用乘,除,取模)

public class ArithmeticoperatorDemo1 {
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int a=sc.nextInt(),b=sc.nextInt();
        //30,10;减三次10得到0,商是3,余数是0;
        //31,10;减三次得到1,1不足以再减10,商是3,余数是1。
        int ans=0;
        while(a>=b){
            ans++;
            a-=b;
        }
        System.out.println("商:  "+ans+"\n余数:"+a);
    }
}

do...while循环(先执行后判断):

初始化语句;

do{

循环体语句;

条件控制语句;

}while(条件判断语句);

三元运算符:

条件?表达式1:表达式2; 两个表达式必须有返回值

public class ArithmeticoperatorDemo1 {
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int a=sc.nextInt(),b=sc.nextInt();
        //a==3? System.out.println("a==3"):System.out.println("a!=3");
        //sout返回类型是void,不能用作三元运算符的表达式。
        String res=(a==3)?"a==3":"a!=3";
        System.out.println(res);
    }
}

无限循环:

for(;;){}

while(true){}

do{}while(true)

跳转控制语句:

continue,break;

平方根计算:

public class ArithmeticoperatorDemo1 {
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int x=sc.nextInt(),a=1;//16,17,25
        while((a*a)<x){++a;}
        int res=(a*a==x)?a:a-1;
        System.out.println(res);
    }
}

判断是否为质数:

public class ArithmeticoperatorDemo1 {
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int x=sc.nextInt(),flag=1;
        for(int i=2;i<=x/2; i++){//可优化为i<=x的平方根(比如19,从%2开始一直到%4,
        //按目前循环里本该到%9,但是从5开始,5*5>19,也就是说%5及以后的数字如果能除尽,它的商必然小于5,也就是0~4,但是前面的循环过程已经验证了0~4不可能为商,后面的情况同理,因此可直接优化到它的平方根4即可)(其他例子同理)
            if(x%i==0){
                flag=0;break;
            }
        }
        if(flag==0){ System.out.println("不是质数");}
        else
            System.out.println("是质数");
    }
}

生成随机数:

import java.util.Random;
public class ArithmeticoperatorDemo1 {
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        Random r=new Random();
        /*for(int i=0; i<100; i++){
            int x=r.nextInt(100);//0~99
            System.out.println(x);
        }*/
        for(int i=0; i<100;i++){
            int x=r.nextInt(100)+1;//1~100
            System.out.println(x);
        }
    }
}

数组:

一种容器,可以用来存储同种数据类型的多个值

(数组在存储数据时,需要结合隐式转换考虑)

eg:

int类型的数组可以存byte,short,int,但是不可以存boolean,double.

double类型的数组可以存byte,short,int,float,double.

数组的定义和静态初始化:

·int[] arr;

·int arr[];

静态初始化:

·int[] arr = new int[]{1,2,3};//或简单写法:int[] arr={1,2,3};(初始化,就是在内容中为数组开辟空间,并将数据存入容器中的过程)arr索引不能超过2

·double[] arr = new double[]{1.1,2.2,3.3};//同理

public class ArithmeticoperatorDemo1 {
    public static void main(String[] args){
        int[] arr=new int[]{1,2,3};
        System.out.println(arr);//[I@31befd9f
    }
}

[I@31befd9f是该数组在内存中的位置

[:表示是一个数组

I:表示是Int类型

@:无含义,表示一个间隔符号(固定格式)

31befd9f:才是数组真正的地址值(十六进制)

数组元素访问:

arr[i];

获取数组长度

arr.length;

动态初始化:

int[] arr= new int[3];//在创建时,我们自己指定数组的长度,由虚拟机给出默认的初始化值

数组默认初始化值的规律:

整数类型:默认初始为0

小数类型:默认初始为0.0

字符类型:默认初始化值'/u0000'空格

布尔类型:默认初始值false

引用数据类型:默认初始值null

将数组元组打印在同一行而不是换行打印

public class ArithmeticoperatorDemo1 {
    public static void main(String[] args){
        int[] arr=new int[]{1,2,3};
        System.out.println(arr);
        for(int i=0; i<arr.length;i++){
            System.out.print(arr[i]+" ");//1 2 3
        }
    }
}

java内存分配:

:方法运行时使用的内存,比如main方法运行,进入方法栈中执行。

:存储对象或者数组,new来创建的,都存储在堆内存,如果new了多次,那么在堆里就有多个小空间,每个空间中都有各自的数据。

方法区:存储可以运行的class文件。

本地方法栈:JVM在使用操作系统功能时的时候使用,和我们开发无关。

寄存器:给CPU使用,和我们开发无关。

  • Java 里只要是 new 出来的东西 → 全在堆

  • 数组本质就是对象 → 全在堆

  • 静态初始化 {1,2,3} 底层等价于 new int[]{1,2,3} → 还是堆

  • 只有基本数据类型(int a=10)才在栈,引用类型都在堆

  • eg:int[] arr=new int[5]; arr这个引用变量在栈,new int[5]这个数组本体在堆。“=”相当于把数组本体的地址赋值给arr。

  • eg:int[] arr={1,2,3,4,5}; arr这个引用变量在栈,{1,2,3,4,5}这个数组本体在堆

两个数组指向同一个空间的情况:

int[] arr1={1,2,3};
int[] arr2=arr1;//相当于把arr1的地址赋值给了arr2,此时它们指向同一个数组。且二者操作相互同步。