运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。参与运算两边类型相同
Java中有算术运算符、关系运算符、位运算符、逻辑运算符、赋值运算符 和 其他运算符。
1.1算术运算符a=10,b=20
| + | 加 | a+b=30 |
|---|---|---|
| - | 减 | a-b=-10 |
| * | 乘 | a*b=200 |
| / | 除 | a/b=1/2 |
| % | 取余/取模 | b%a=0 |
| ++ | 自加 | a++=11 ,++a=11 |
| – | 自减 | a–=9 , --a=9 |
自增(++)自减(–)运算符是一种特殊的算术运算符,在算术运算符中需要两个操作数来进行运算,而自增自减运算符是一个操作数。
前缀自增自减法(++a,–a): 先进行自增或者自减运算,再进行表达式运算。(先加再算)
后缀自增自减法(a++,a–): 先进行表达式运算,再进行自增或者自减运算 实例:(先算再加)
//自加符 int i=10; int j= i++;//右自增 先赋值在运算 结果:j=10 i=11 int k= ++i; //左自增 先运算再赋值 结果:k=12 i=12 //i=12 i=i++ 当把12赋值给i 时 ,不会两次赋值,运算后则为12 i=++i i为13 // 自减符-- // += int i=0; i+=3; //相当于 i=i+31.2关系运算符
所有的关系运算符的运算结果都是布尔类型,不是true就是false,不可能是其他值。
| 操作符 | 例子 |
|---|---|
| > | 大于 |
| >= | 大于等于 |
| < | 小于 |
| <= | 小于等于 |
| == | 等于 |
| != | 不等于 |
Java定义了位运算符,应用于整数类型(int),长整型(long),短整型(short),字符型(char),和字节型(byte)等类型。
位运算符作用在所有的位上,并且按位运算。
下表列出了位运算符的基本运算,假设整数变量A的值为60(二进制:0011 1100)和变量B的值为13(0000 1101):
| 操作符 | 描述 | 例子 |
|---|---|---|
| & 与 | 如果相对应位都是1,则结果为1,否则为0 | (A&B),得到12,即0000 1100 |
| | 或 | 如果相对应位都是0,则结果为0,否则为1 | (A|B), 得到61,即 0011 1101 |
| ^ | 如果相对应位相同,则结果为0,否则为1 | (A ^ B)得到49,即 0011 0001 |
| 〜 | 按位取反运算符翻转操作数的每一位,即0变成1,1变成0。 | (〜A)得到-61,即1100 0011 |
| << | 按位左移运算符。左操作数按位左移左操作数指定的位数。 | A << 2得到240,即 1111 0000 |
| >> | 按位右移运算符。右操作数按位右移右操作数指定的位数 | A >> 2得到15, 即 0000 1111 |
所有的关系运算符的运算结果都是布尔类型,不是true就是false,不可能是其他值。
| 操作符 | 描述 | 例子 | |
|---|---|---|---|
| & | 逻辑与(并且) | 两边都是true,结果才是true | 有假则为假 |
| │ | 逻辑或(或者) | 有一边是true,结果就是true | 有真即为真 |
| ! | 逻辑非(取反) | !true = false , !false = true | |
| && | 短路与 | 两边都是true,结果才是true | 只要左边为flate 右边不运算 |
| ││ | 短路或 | 有一边是true,结果就是true | 只要左边为true 右边不运算 |
首先这两个运算符的运算结果没有任何区别,完全相同。
只不过“短路与&&”会发生短路现象。
//测试逻辑与& int x = 10; int y = 11; System.out.println(x > y & x > y++); //false //通过这个测试得出:x > y++ 这个表达式执行了。 System.out.println(y); // 12 //测试短路与&& int m = 10; int n = 11; // 使用短路与&&的时候,当左边的表达式为false的时候,右边的表达式不执行 // 这种现象被称为短路。 System.out.println(m > n && m > n++); System.out.println(n); // 111.42什么是短路现象?
右边表达式不执行,这种现象叫做短路现象。
1.43什么时候使用短路与&&,逻辑与& ?从效率方面来说,&&比&的效率高一些。
因为逻辑与&不管第一个表达式结果是什么,第二个表达式一定会执行。
以后的开发中,短路与&&和逻辑与还是需要同时并存的。
大部分情况下都建议使用短路与&&只有当既需要左边表达式执行,又需要右边表达式执行的时候,才会选择逻辑与&。
首先这两个运算符的运算结果没有任何区别,完全相同。
只不过“短路或 ||”会发生短路现象。
//测试逻辑或| int x = 10; int y = 11; System.out.println(x < y | x > y++); //ture // 通过这个测试得出:x > y++ 这个表达式执行了。 System.out.println(y); // 12 //测试短路或|| int m = 10; int n = 11; // 使用短路或||的时候,当左边的表达式为true的时候,右边的表达式不执行 // 这种现象被称为短路。 System.out.println(m < n || m > n++); System.out.println(n); // 111.45逻辑符运算符例子
//布尔值表达式 逻辑运算符 布尔值表达式
1==1 & 2==2; t
1!=1&2==2; f
1!=1|2==2; true
1!=1&& 2==2; 2==2 不需要判定
1==1 || 2==2; t 右边不需要判定
1.5赋值运算符
| 运算符 | 含义 | 例子 |
|---|---|---|
| = | 赋值,右边的赋值给左边的 | C = A + B将把A + B得到的值赋给C |
| += | 加等,左操作数和右操作数相加赋值给左操作数 | C + = A等价于C = C + A |
| -= | 减等,把左操作数和右操作数相减赋值给左操作数 | C - = A等价于C = C - A |
| *= | 乘等 | C * = A等价于C = C * A |
| /= | 除等 | C / = A等价于C = C / A |
| %= | 取模赋值操作符 | C%= A等价于C = C%A |
| << = | 左移位赋值运算符 | C << = 2等价于C = C << 2 |
| &= | 按位与赋值运算符 | C&= 2等价于C = C&2 |
| ^ = | 按位异或赋值操作符 | C ^ = 2等价于C = C ^ 2 |
| |= | 按位或赋值操作符 | C|= 2等价于C = C|2 |
除了第一个是赋值运算符,其他都是拓展赋值运算符
使用扩展赋值运算符的时候,永远都不会改变运算结果类型。
1.6条件运算符 1.61三目运算符/三目运算符语法格式:布尔表达式 ? 表达式1 : 表达式2
只能写值的赋予
赋值表达式,最终一定会返回一个值,可以嵌套使用
1.62执行原理是什么?布尔表达式的结果为true时,表达式1的执行结果作为整个表达式的结果。
布尔表达式的结果为false时,表达式2的执行结果作为整个表达式的结果。
char a = true ? '男' : "女"; string a1 = true ? '男' : "女"; 以上两个都报错。 //下面可以 String s = ""; s += true ? '男' : "女";
int i=100;
char c =i>=100? 'A':'B'
char c =i> 100? 'A': i>=90?'B' : 'C';
//对mark判定,大于90则为A,80-90为B,70-80为C,60-70为D,否则为E
int mark=100;
char level=mark>=90? 'A': mark>=80? 'B': mark>=70? 'C': mark>=60? 'D': 'E';
//局部变量在同一个作用域内不能同名
int mark=100;
char c;
if( mark>=90){
c= 'A';
}else if( mark>=80){
c='B';
}else if( mark>=70 ){
c= 'C';
}else if(mark>=60){
c= 'D';
}else{
c= 'E';
}
//如果if的花括号内只有一行语句 可以忽略{}
if(true) int i=100;
if (true){
int i =100;
}
1.7运算符题目
int i=10;
int k=10;
i++>10 && i++>k 10>10 false 左边为false,右边不运算 f i=11 k不变
++i >k || --k>8 11>10 true 左边为真,右边不运算. t i=11 k=10
i-->k-- || i++>=k 10>10 false 9>= 9 true t i=10 k=9
i++>--k && i-->k 10>9 true 11>9 true t i=10 k=9
i++>--k || i-->--k 10>9 true t i=11 k=9
//按照 参与运算的最大的数据类型输出
10/3 3
10/3.0 3.3333
jshell> char c ='a'+'b'
c ==> '?'
jshell> char d=1+1
d ==> ' 02'
1.8类型转换
运算时,byte short char 不会相互转换,直接视为 int
隐式转换 byte short char int long float double
int i='a' 合法 //i=97
short s=100 合法 //s=100
byte b=i 不合法 //变量 ,从int转换到byte可能会有损失
byte b2=100 合法 //b2=100
short s2=b2+b2 不合法 //从int转换到short可能会有损失,大类型转小类型
char c =b2 +b2 不合法 //从int转换到char可能会有损失,大类型转小类型
short s3=100+100 合法 //s3=200
float f =1.0F +(1+1.0)+ (float)1.0 不合法 // 从double转换到float可能会有损失
float f =1.0F +(float)(1+1.0)+ (float)1.0 合法//f=4.0
double d=i+i+1.0 合法
float f2=1.0F 合法 //fa2=1.0
float f2=1.0 不合法 // 从double转换到float可能会有损失
f2-0.1 ==0.9 true //都是double
f-0.1F==0.9 false //float转为double
byte b=99999999999 //过大,超出byte范围
1.9字符串连接运算符(+)
+运算符在java语言中有两个作用。
作用1:求和
作用2:字符串拼接
什么时候求和?什么时候进行字符串的拼接呢?
当 + 运算符两边都是数字类型的时候,求和。
当 + 运算符两边的“任意一边”是字符串类型,那么这个+会进行字符串拼接操作。
一定要记住:字符串拼接完之后的结果还是一个字符串。
int a = 100; int b = 200; // 这里的 + 两边都是数字,所以加法运算 int c = a + b; System.out.println(a + "+" + b + " = " + a + b);//100+200=100200 字符拼接 System.out.println(a + "+" + b + " = " + (a + b));//100+200=300 数字计算
遵循“自左向右”的顺序依次执行(除非额外添加了小括号,小括号的优先级高)
二、流程控制 2.1顺序结构int i=10; int j=10; int k=i+j;2.2分支结构 2.21 if else
//从上到下挨个匹配,直到有个符合条件
if (布尔值表达式) {
//todo
}else if(布尔表达式){
//todo
}else{
//以上情况都不符合
}
//{}变量的作用域
int k=100;
if(true){
int k=10;
}else{
int y=k+100;
}
// 对mark判定
int mark=100;
char level= mark>=90? 'A': mark>=80? 'B': mark>=70? 'C': mark>=60? 'D' : 'E';
//局部变量在同一个作用域内不能同名
int mark=100;
char c;
if( mark>=90){
c= 'A';
}else if( mark>=80){
c='B';
}else if( mark>=70 ){
c= 'C';
}else if(mark>=60){
c= 'D';
}else{
c= 'E';
}
//如果if的花括号内只有一行语句 可以忽略{}
if(true) int i=100;
if (true){
int i =100;
}
2.22 switch …case
对变量进行判定,进行精确判定,不会从上到下匹配,直接进入符合条件的分支,如果没有,进入default分支
break的作用 跳出花括号,防止break 向下执行.
只能针对变量,效率比if高
//变量只能是基本数据类型中的 byte char short int 和引用数据类型String
switch (变量){
case 值:
break;
case 值:
break;
...
default :
break;
}
//例子
int i=100;
switch(i){
case 100:
System.out.println("i的值是100");
break;
case 90:
System.out.println("i的值是90");
break;
default:
System.out.println("i的值是100");
}
println 打印并换行
print 打印
System.out.printf()
2.23字符串String
引用数据类型 ,所有引用类型首字母大写
//在java中单引号表示字符,双引号表示字符串
String s1="a";
String s='a'+'b'; 错误 //右边返回int数据类型, int无法转换为java.lang.String
//什么地方出现字符串,什么时候就是字符串的拼接
//字符串的拼接
System.out.println(1+2+3+"我"+"我们"+12); //6我我们12
System.out.println("我"+"我们"+"1"+"2222"); //我我们12222
//switch case用法
String aut="春天";
switch (aut){
case"春天" :
System.out.println("春天345");
break;
case"夏天" :
System.out.println("夏天567");
break;
case"秋天" :
System.out.println("秋天8910");
break;
case "冬天":
System.out.println("冬天1112");
break;
default :
System.out.println("非法");
break;
}
//去掉break 尝试 看输出结果
2.3循环结构
2.31 for循环
for(初始值表达式;布尔值表达式;值改变表达式){
//todo 循环体
}
//1 常规写法
for(int i=1;i<=10;i++){
System.out.println(i);
}
//2 在外面声明变量
int i=1;
for(;i<=10;i++){
System.out.println(i);
}
//3 布尔值表达式放里面
int i=1;
for(;;i++){
if(i>10)break;
System.out.println(i);
}
//4 值改变表达式放里面
int i=1;
for(;;){
if(i>10)break;
System.out.println(i);
i++;
}
for循环例子
//输出1-50的所有偶数 ,用两种方法
//能被2整除的就输出,加判断条件
for(int i=1;i<=50;i++){
if(i%2==0)
System.out.println(i);
}
//改变初始值表达式和值改变表达式
for(int i=2;i<=50;i+=2){
System.out.println(i);
}
//continue用法
//continue 跳出本次循环
//break 跳出本层循环
for(int i=1;i<=50;i++){
if(i%2!=0)continue;
System.out.println(i);
}
//九九乘法表 %d占位符
for(int i=1;i<10;i++){
for(int j=1;j<=i;j++){
System.out.printf("%d*%d=%d ",j,i,i*j);
}
System.out.println();
}
//
for(int i=1;i<10;i++){
for(int j=1;j<10;j++){
System.out.print(j+"x"+i+"="+j*i+"t");
};
System.out.println();
}
//左下角直角三角
*
**
***
****
for(int i=1;i<10;i++){ //i控制行数
for(int j=1;j<=i;j++){ //j控制列数
System.out.printf("* ");
}
System.out.println();
}
//菱形
int hight=9;
int top=hight%2 ==0? hight/2: hight/2+1;
int left=top;
int right=top;
for (int i=1;i<=hight;i++ ){
String line="";
for(int j=1;j<=hight;j++){
line+= j>=left && j<= right? "* ": " ";
}
if(i
2.32 while do
while(布尔值表达式){
}
//输出1-10
int i=1;
while(i<=10){
System.out.println(i);
i++;
}
2.33 do while
至少执行一次循环
do{
}while(布尔值表达式);
//1-10
int i=1;
do{
System.out.println(i);
i++;
} while(i<=10);
三、数组array
3.1数据的定义
存储指定数据类型和固定长度的元素集合
创建拥有指定数据类型并有固定长度,创建成功无法进行修改, 数据类型不能修改,长度无法改变,内容可以,
是引用数据类型
//如何创建数组
//静态数组
int [] arr={1,2,3,4,5} // 创建一个 int数组,长度是5,存放元素 1 2 3 4 5
int arr[]={1,2,3,4,5 } //两种写法
arr={1,2,3}; //非法
//动态数组
int [] arr= new int[5]; //创建了个固定长度5的数组,内容默认为{0,0,0,0,0}
int []arr=new int[]{1,2,3,4,5};
String [] arr = new String[5]; //内容默认为null
int [] arr=new int[] //非法,数组必须有长度
3.2数组的使用
//根据偏移量获取对应元素 偏移量 index 最小0 最大 (长度-1)
int [] arr={1,2,3,4,5}
//通过数组名[下标]获取对应的元素
int i =arr[0];//1
int i1 =arr[1];//2
arr[0]=100; 将下标为0的元素,修改为100
3.3数组的遍历
forEach
增强for循环 forEach ,专门用于遍历集合和数组
for(数据类型 变量名:需要遍历的数组){}
//遍历数组
int arr[]={1,2,3,4,5,6,7};
//length 数组的长度
for( int i=0;i
3.4数组的操作
//数组中增加元素
int[] arr={1,2,3,4,3,4,5,6,12,13}
//向数组中加100
//创建原数组长度+1,将原数组的元素放入新数组中,在最后添加100,重新赋值
int [] copyArr =new int[arr.length+1];
//原数组的内容放入新数组
int index=0;
for(int i: arr){
copyArr[index++]=i;
}
copyArr[index]=100; //将下标为0的加元素100
arr=copyArr; //将copyArr数组赋值给数组arr
//数组中移除元素
//移除数组中的元素 ,移除3
int[] arr={1,2,3,4,3,4,5,6,12,13}; //移除所有3
int count =0;
for(int i:arr){
if(i==3)count++;
}
if(count>0){
//新数组的长度
int []copyArr = new int[arr.length-count];
int index =0;//新数组的下标
for(int i :arr){
if(i!=3){
copyArr[index++]=i;
}
}
arr = copyArr;
}
//移除第一个3 3之后的所有元素向前移动一位,并且最后一位改为0
int[] arr={1,2,3,4,3,4,5,6,12,13};
int index=-1; //记录第一个3的下标
for(int i=0;i-1){
for(int i=index;i
3.5数组的排序
//插入排序
int arr[]={ 13,1,8,0,9,17,21,6,3 };
for (int i=1;i=0&&target
3.6内存划分 jvm
栈 stack:栈的空间较小,使用效率非常高,程序员无法手动申请,jvm自动调用
堆heap: 堆的空间较小,使用效率非常低,程序员手动申请 new
只要在堆中出现的引用数据类型,都有默认值null
3.7冒泡排序
//数组{13,21,7,1,0,19,5,3} 大的往下沉
int arr[]={13,21,7,1,0,19,5,3};
//外层表示 循环的次数 ,也是 有序区 的长度
for(int j=0;jarr[i+1]){
//将较大的数 放入 数组的尾部
int temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
}
//小的数字在数字的开头
int arr[]={13,21,7,1,0,19,5,3};
//外层循环的次数
for (int j=0;jj 有序区在头部
for(int i=arr.length-1;i>j;i--){
if(arr[i]
3.8二分查找法
有序数组才能使用
int arr[]={0,1,2,3,4,5,6,7};
//arr 有序数组
int low=0; //最小下标
int hight=arr.length-1; //最大下标
int target =19;
int index=-1;
while(low<=hight){
int middle = (low+hight)/2; //中轴
if (arr[middle]==target){
index=middle;
break; //找到之后停止
}
if(arr[middle]target)hight=middle-1; //比中轴小,最大下标移动
}
3.9二维数组
//一维数组
int arr[]={ 1,2,3,4};
//二维数组的写法
int arr [] []={{1,2},{1,2}}
int [] [] arr={{2},{1}}
int [] arr[]={{1,2},{1,2}}
//动态数组的创建
int[][] arr=new int[3] [];//合法
int[][] arr=new int[3][3];//合法
//二维数组的遍历
//二维数组遍历的理解
int arr [] []={{1,2},{1,2}}
arr[0] {1,2}
arr[0][0] 1
//
int [][]arr={{1,2,3},{4,5,6},{7,8,9}};//创建二维数组
for (int i=0;i
四、方法method
方法由两部分构成 方法的声明 方法体
4.1 void
void 该方法没有返回值
4.2 return
return 有返回值
//方法声明部分 void get()
// {}花括号里的是方法体
void get( ){
}
//冒泡排序
void bubbleSort (int[] arr){
for(int j=0;jarr[i+1]){
//将较大的数 放入 数组的尾部
int temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
}
}
//执行 bubbleSort (int[] arr)
int arr[]={1,2,3,4}
int arr1[]=arr //右边是值的传递,在堆空间内
arr1[0]=99
arr[0] // 也是99
堆只有一个,栈有多个.
//有返回值的方法
//return 结束方法 也可以返回对应值
//return方法执行完毕,之后的语句无法执行,并且也不能添加语句
//必须返回结束值类型对应的数值
int get(){
return 10; //方法执行完毕 返回 整数10
}
get() //执行 ,返回10
int get(){
return 10;
int i=1;
} //错误 验证return后的语句不能执行
int get(){
if(1!=1) return 10; //if为分支结构,则后面的语句可以执行
}
double get(){
return;
}
//栈帧
//方法的运行在栈中
//方法中声明出来的变量都是局部变量
//引用数据类型指向堆中,引用数据类型才需要new
//局部变量只在他自己方法的栈中
//栈的特点 先进后出,从最底部开始到顶部
int test(int i){
int j=i*100;
int k=j+100;
System.out.println(k);
return k;
}
test(1)//执行
void test2(){
int i=100;
test(i);
}
test2(); //test2方法必须等test方法结束
//无限循环调方法,最后报错 栈溢出 StackOverflow 栈溢出
void print(){
System.out.print(12);
print();
}
//递归 在重复处理一件事上效率更好
// 递归一定要有停止条件,如果不停止,会报错 栈溢出
//加法
int add(int i,int j){
if(i>j)return 0;
return i++ + add(i,j);
}
add(1,5)
(1+(2+(3+(4+(5+0)))))=15
//减法
int minus(int i,int j){
if(i>j)return 0;
return i++ - minus(i,j);
}
add(1,5)
1-(2-(3-((4-(5-0)))))=3
// 方法
void print(int i,int j){
if(i>j)return;
System.out.println(i++);
print(i,j);
}
print(int 1,int 2)



