注释:
单行://
多行:/* */
文档:/** */
关键字的字母全部小写
类(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(表达式){
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
………
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,此时它们指向同一个数组。且二者操作相互同步。