文章目录
浮点型
- 浮点数 = 符号位 + 指数位 + 尾数位
double a = 0.123
中的0
默认可以省略5.12e2 = 5.12*10
的2
次方5.12E-2 = 5.12/10
的2
次方 (其中e
的大小写无关)- 对小数进行计算时,返回的结果并不是准确值,不能跟数学一样准确,是计算机的问题,计算机不清楚你的小数位数后面是否还有。所以当两个运算结果是小数且值相同时要小心,应该比较两个数的差值的绝对值在某个精度范围内即可判断相等。
Java API
- 绝对值的方法:
Math.abs()---->java
的API
文档:java
提供的基本编程接口,提供了大量的基础类
API
文档中均可找到对应的模板。API文档
字符型
char
类型可以直接存放数字,也可存放一个汉字,如char a = 97
- 字符常量需要用单引号,若用双引号则为字符串,会发生报错
- char的本质是整数,默认按照
unicode
码对应的字符输出,要想输出对应的数字,可以使用(int)字符。 char name = 97
,则运行结果显示为a。char
类型可以进行运算,相当于一个整数,因为他都有对应的Unicode码ascii
码一个字节表示128
个字符,实际上可表示256
个字符unicode
码兼容ascii码。- utf-8是一种变长的编码方式,根据不同的符号变换字节的长度。
- 布尔类型不可转化为
0
或1
,只能是true
或者false
。
自动类型转换
- 精度小的类型可以自动转化为精度大的类型
- 有多种类型的数据混合运算时,系统首先会自动将所有的数据转换成容量大的数据类型,然后再进行计算。
- 精度大的数据类型赋给精度小的数据类型会进行报错,反之进行自动类型转换。
- (byte,short)和char不会相互进行自动转换。
- 当把一个具体数值赋值给byte时,先判断数值是否在-128~127之间;如果按变脸赋值,则先判断类型,如:int不可转为byte。
- byte、short、char三者可以进行计算,但在计算之前首先转化为int类型。即使是两个byte类型的数据进行计算,结果也会被转化为int类型。
- 布尔类型不参与类型的自动转换。
- 表达式中结果的类型自动提升为操作数中最大的类型。
强制类型转换
- 加上强制转换符(),可能造成精度损失或者数据溢出溢出。例如:
int i =
(int)1.9; byte b1 = (int)j;
- 数据精度进行从大到小时,需要进行强制类型转换。
- 强制符号只针对最近的操作数有效,往往需要小括号提升优先级。
char
类型可以保存int
的常量值,但保存int
的变量值需要强制转换(类型不匹配)。- 布尔类型可以强转为int型
基本数据类型和string类型的转换
- 基本数据类型转为
string类
型:直接给基本数据类型加双引号。 string
类型转为基本数据类型:通过基本类型的包装类调用parsexxx
方法即可。- 字符串转为字符
char
:得到字符串的第一个字符。例如:s5.charAt(0)
:得到s5字符串的第一个字符;s5.charAt(1)
:得到s5
字符串的第二个字符。 string
类型转为基本数据类型前,要确保string
类型可以转换为有效的数据,如把字符串“123”
转为一个整数,但不能把“hello”
转为一个整数。
算数运算符
- 取余得到的结果,最终的符号看被除数的正负。
- 取余操作数通常是正整数也可以是负数甚至是浮点数,而c语言必须是整型。
i++
作为独立语句使用时,前++
和后++
结果相同。- 作为表达式使用时,不一定相同。
关系运算符
- 结果都是布尔型,结果不是
true
就是false
; instanceof
来检查是否是类的对象。
逻辑运算符
- 用于连接多个表达式,最终的结果都是布尔类型。
- 短路与
&&
:如果第一个条件为false,则第二个条件不会判断,最终结果为false; - 逻辑与
&
:不管第一个是否为false,第二个条件也会判断,效率较低,开发中我们使用的多为短路与和短路或。
赋值运算符
- 赋值运算符的顺序是从右向左,即先等号右边,后是等号左边。
- 左边只能是变量,右边可以是变量、表达式、常量值。
- 复合赋值运算会进行类型转换。例如:
byte b=3; b = b+3
---->报错,会提示int转为byte会有精度损失,而byte b=3; b+=3
----->即可编译成功,进行强制转化运行结果为(byte)(b+3)
。
三元运算符
- 条件表达式?表达式1:表达式2
- 若运算结果为true,则运算结果为表达式1,否则为表达式2。
- 表达式1和表达式2的变量类型应该与接收变量的类型一致(自动类型转换或者强转均可)。
运算符优先级
- 上一行的符号总优先于下一行
- 只有单目运算和赋值运算由右向左。
标识符的命名规则和规范
- 标识符的概念:
Java
中对各种变量、方法和类命名时所使用的字符称为标识符,即凡是可以自己起名字的地方叫做标识符。 - 标识符的命名规则:
1> 由26个英文字母大小写,0-9
,_
,$
组成。
2> 数字不可以开头
3> 不可以使用关键字和保留字,但能包含关键字和保留字【关键字和保留字百度查表】。
4> Java中严格区分大小写,但长度无限制。 - 标识符的规范:
1> 包名:多单词组成时所有字母都小写且用点进行间隔:aaa.bbb.ccc
2> 类名、接口名:多单词组成时所有单词首字母大写XxxYyy
。---->大驼峰法
3> 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始首字母大写。---->小驼峰命名法
4> 常量名:所有字母大写。且多单词时每个单词使用下划线连接。
关键字
- 定义:被java语言赋予了特殊的含义,用作专门用途的字符串
- 特点:关键字中所有字母都为小写
- 具体哪些关键字自己百度查表
保留字
- 现有Java版本尚未使用,但有的版本可能作为关键字使用,自己命名时要避免使用,如
byValue、cast、future、generic、inner、operator、outer、rest、var、goto、const。
从键盘输入
- 程序运行到
next
的时候,即等待从键盘输入。
进制介绍
- 二进制:以
0b
或者0B
开头。 - 八进制:以数字
0
开头表示,八进制中10
表示8
。 - 十六进制:
0-9
和A(10)-F(15)
【不区分大小写】,以0x
或者0X
开头。
进制转换
- 二进制转十进制:从最低位即最右边开始,每个位数上的数提取出来乘以2的(位数-1)次方,然后求和。
- 八进制转十进制:从最低位即最右边开始,每个位数上的数提取出来乘以8的(位数-1)次方,然后求和。
- 十六进制转十进制:从最低位即最右边开始,每个位数上的数提取出来乘以16的(位数-1)次方,然后求和。
- 十进制转二进制:将该数不断除以2,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制,前面还要加0b。—>一个字节有八位,因此得到的二进制数还要在最前面加0直到为八个字节,不包括0b。
- 十进制转为八进制:将该数不断除以8,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制,前面要多加一个0。
- 十进制转十六进制:将该数不断除以16,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制,前面要多加一个0x。
- 二进制转八进制:从最低位即最右边开始,将二进制数每三位一组,转成对应的八进制即可。
- 二进制转十六进制:从最低位即最右边开始,将二进制数每四位一组,转成对应的十六进制即可。
- 八进制转二进制:从最低位即最右边开始,将八进制的每一位数,转为对应的一个3位的二进制数。
- 十六进制转二进制: 从最低位即最右边开始,将八进制的每一位数,转为对应的一个4位的二进制数。
原码,反码,补码
对于有符号的数而言:
- 二进制的最高位即最左边是符号位,0表示正数,1表示负数。
- 正数的原码反码补码都一样。
- 负数的反码 = 它的原码符号位不变,其他位取反【即0变1,1变0】。
- 负数的补码 = 负数的反码+1。
- 0的反码、补码都是0。
- Java没有无符号数,换言之,Java中的数都是有符号的。
- (****)计算机运算时,都是以补码的方式来运算的。
- 当我们看运算时,要看他的原码。
位运算
-
Java中有7个位运算符(
&、|、^、~、>>、<<、>>>
)。 -
按位与&:两位全为1,结果为1;否则为0。
-
按位或|:两位中有一个为1,结果为1;否则为0。
-
按位异或^:两位中一个为0,一个为1,则结果为1;否则结果为0。
-
按位取反~:
0->1,1->0
。 -
例1
-
例2
-
例3- 算数右移
>>
:低位(最右边的数)溢出,符号位(最左边的数)不变,并用符号位补溢出的高位。 -
算数左移
<<
:符号位不变,低位补0
。 -
>>>
逻辑右移也叫无符号右移,运算规则是低位溢出,高位补0
。 -
没有
<<<
符号。 -
例1
a >> b --> a/(2的b次)
a << b --> a*(2的b次)
顺序控制
分支控制
- 单分支
- 双分支
- 多分支
if、else if 、……、else
- 嵌套分支
switch
分支
switch(表达式) {
case 常量表达式1:语句块1;break;
//break表示退出switch,不是退出程序。
.
.
.
default:语句块;break;
}
- 循环控制
for(;;)
—>表示无限循环
for each
循环:用于读取数组元素的值,不能修改元素的值
for(int m:a) { // i为变量,a为数组名
System.out.println(m);
}
while
循环do while
循环
do{
循环体;
循环变量迭代;
}while(循环条件);
break
- 提前退出循环。
- 生成1-100的随机数:
(int) (Math.random()*100)+1
- 标签label可以放在
break
后面,但是不建议使用标签。若break
后面什么都没有,即采取就近原则,跳出最近的循环体。 - 标签名称随意,只要满足标识符的规则即可。
- 字符串的比较
name.equals(" ")
或者" ".equals(name)【开发中较常用,可以避免空指针的问题】
,返回值是true或者false。
continue
- 结束本次循环,继续下一次循环。
- 标签使用原则与
break
相同。
reture
return
表示跳出所在方法,主方法中表示跳出程序。
数组
- 数组是一种数据类型【引用数据类型+基本数据类型】,是引用数据类型【类、数组、接口】,多个同一类型的数据。
double[]
表示double
类型的数组- 数组的定义【动态初始化1】:
数据类型 [] 数组名 = new 数据类型 [大小]
- 动态初始化2:
声明数组 —>
数据类型 [] 数组名
创建数组 ---->数组名 = new 数据类型 [大小]
//正式真正分配存储空间
- 静态初始化
数据类型 [] 数组名 = {元素值,元素值,……}
- 数组使用的注意事项:
- 数组是多个相同类型数据的组合。
- 数组中可以存放任何数据类型,基本数据类型和引用数据类型【对象、数组、接口】,但是不能混用。
- 数组创建后没有赋值,则有默认值。如布尔类型默认
false
,String
类型默认null
。- 使用数组的步骤:声明数组并开辟空间;给数组各个元素赋值;使用数组。
- 数组赋值机制:
- 基本数据类型赋值方式为值传递。
- 数组在默认情况下引用传递,赋的值为地址,赋值方式为引用传递。
arr1
数组输出为10、2、3
。
- 数组拷贝(要求数据空间独立)
int [] arr1 = {10,20,30};
int [] arr2 = arr1; //数组空间共享
int [] arr2 = new int[arr1.length] //new代表开辟新的空间
for(i = 0; i<arr1.length; i++) {
arr2[i] = arr1[i];
}
arr2[0] = 100; //修改arr2[0]的值
- 数组翻转
- 数组扩容
思路分析:
1.定义初始化数组 int[] arr = {1,2,3};
2.定义一个新的数组 int[] arrNew = new int [arr.length+1]
3.遍历arr数组,依次将arr的元素拷贝到arrNew数组。
4.将4赋值给arrNew[arrNew.length-1] = 4
5.将arr指向 arrNew,则原来的arr数组销毁。
6. arr数组输出的结果为1,2,3,4
int[] arr = {1,2,3};
int[] arrNew = new int [arr.length+1]
for (int i=0; i<arr.length; i++) {
arrNew[i] = arr[i];
}
arrNew[arrNew.length-1] = 4 //4为要添加的元素
arr = arrNew;
排序
- 冒泡排序
for(int i=0; i<arr.length-1; i++) { //4轮排序
for(int j=0; j<arr.length-1-i;j++) { //4、3、2、1次比较
if(arr[i]>arr[i+1]) {
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
}
多维数组
- 动态创建二维数组
枚举
package Array;
//定义水果枚举类,设置每种水果的价格,然后输出!
enum Fruit{
apple,banana,pear,peach
}
public class Array3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
double price = 0;
for(Fruit fruit:Fruit.values()) { //创建一个Fruit对象叫做fruit,Fruit.values()就是枚举类的各个值
switch(fruit) {
case apple:price = 4;break;
case banana:price = 3;break;
case pear:price = 2;break;
case peach:price = 1;break;
}
System.out.println(fruit+"的价格为"+price);
}
}
}
数组中各种方法的应用
package Array;
import java.util.Arrays;
import java.util.Scanner;
public class Array2 {
//将一个放有文具英文名称的数组进行排序,并格式化输出原来的数组和排序后的数组,之后从键盘输入一个文具名称,看看是否在数组中?
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] words= {"ruler","rubber","pen","pencil","book","ink","globe"};
String [] words2 = Arrays.copyOf(words,words.length); //复制数组
for(int i=0; i<words2.length; i++) {
System.out.print(words2[i]+"\t");
}
Arrays.sort(words2); //升序排序
System.out.println();
for(int i=0; i<words2.length; i++) {
System.out.print(words2[i]+"\t");
}
System.out.println();
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个文具名称");
String name = sc.next();
int index = Arrays.binarySearch(words2, name); //如果要搜索的元素name在指定的范围内,则返回搜索键的索引;否则返回-1或者”-“(插入点),尤其数组要求有序数组!
if(index >= 0) {
System.out.println("文具" + name + "在数组的" + index + "号位置!");
}
else {
System.out.println("文具" + name + "不存在");
}
}
}