Java 基础
1. 标识符
1.1 组成
数字 字母 下划线(_) $
注:一般不用$,因为后续学习中会用到该符号。
1.2 规则
1.不能以数字开头
2.不能是关键字
注:Class是正确的标识符,但一般不用。
3.区分大小
1.3 约定
标识符的命名规则:见名知意
1.小驼峰命名法:变量、方法的命名
标识符是一个单词时,首字母小写。例:name
标识符是多个单词组成时,第一个单词首字母小写,从第二个开始后面的每个单词的首字母大写。例:firstName
2.大驼峰命名法:类名、接口名的命名
每个单词的首字母都大写。例:FirstName
2. 数据类型
2.1 自动类型转换
数据范围小的数值或者变量赋值给另一个表示数据范围大的变量
byte、short、char之间不会相互转换,在计算时先转换为int类型
注:常见错误
1.byte、short、char的运算
public class aaa
{
public static void main(String[] args)
{
//byte、short、char的运算
byte a = 9;
short b = 100;
short c = a + b;
System.out.println(c);
}
}
E:\Java\javawork\work1\test.java:6:21 //byte、short、char的运算,要先转换为整型,故计算所得的c为int型,转换为short可能会有精度损失
java: 不兼容的类型: 从int转换到short可能会有损失
2.2 强制类型转换
数据范围大的数值或者变量赋值给另一个表示数据范围小的变量
格式:目标数据类型 变量名 = (目标数据类型)值或者变量
例:
int k = (int)88.8
注:可能造成精度降低或溢出。
例:
public class test{
public static void main(String[] args) {
//强制类型转换
float a = 11.1;
short b = (short)a;
System.out.println(b);
}
}
E:\Java\javawork\work1\test.java:4:19
java: 不兼容的类型: 从double转换到float可能会有损失
2.3 BigDecimal
(原文链接:https://blog.csdn.net/qq_35868412/article/details/89029288)
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算
数据类型
BigDecimal(int) 创建一个具有参数所指定整数值的对象。
BigDecimal(double) 创建一个具有参数所指定双精度值的对象。 //不推荐使用
BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。//推荐使用
示例:
BigDecimal str = new BigDecimal("22"); //22
System.out.println("str = " + str);
BigDecimal intStr = new BigDecimal(11); //11
System.out.println("intStr = " + intStr);
BigDecimal doubleStr = new BigDecimal(11.1111111); //11.1111111000000004622734195436351001262664794921875
System.out.println("doubleStr = " + doubleStr);
BigDecimal(double) 的替换方式:
- Double.toString(d) 转换为 String
- BigDecimal.valueOf(d)
double d = 1.11111111;
BigDecimal doubleToStr = new BigDecimal(Double.toString(d)); //doubleToStr = 1.11111111
System.out.println("doubleToStr = " + doubleToStr);
BigDecimal doubleToStr2 = BigDecimal.valueOf(d); //doubleToStr2 = 1.11111111
System.out.println("doubleToStr2 = " + doubleToStr2);
BigDecimal bigDecimal = new BigDecimal(d); //bigDecimal = 1.111111109999999957409499984350986778736114501953125
方法
方法 | 说明 |
---|---|
add(BigDecimal) | BigDecimal对象中的值相加,然后返回这个对象 |
subtract(BigDecimal) | BigDecimal对象中的值相减,然后返回这个对象 |
multiply(BigDecimal) | BigDecimal对象中的值相乘,然后返回这个对象 |
divide(BigDecimal) | BigDecimal对象中的值相除,然后返回这个对象 |
toString() | 将BigDecimal对象的数值转换成字符串 |
doubleValue() | 将BigDecimal对象中的值以双精度数返回 |
floatValue() | 将BigDecimal对象中的值以单精度数返回 |
longValue() | 将BigDecimal对象中的值以长整数返回 |
intValue() | 将BigDecimal对象中的值以整数返回 |
示例:
BigDecimal a = new BigDecimal("3");
BigDecimal b = new BigDecimal("4");
BigDecimal addStr = a.add(b); // 7 相加
BigDecimal subtractStr = a.subtract(b); // -1 相减
BigDecimal multiplyStr = a.multiply(b); // 12 相乘
BigDecimal divideStr = a.divide(b); // 0.75 相除
BigDecimal divideStr1 = a.divide(b, 1, BigDecimal.ROUND_HALF_UP); // 0.8 相除,保留一位小数
double c = 1.23;
BigDecimal doubleStr = new BigDecimal(c);
BigDecimal doubleToStr = new BigDecimal(Double.toString(c)); //1.23 将double转为String
int doubleToInt = doubleStr.intValue(); //1 将BigDecimal double转为int
在做除法时,若不能整除,会报异常,此时需要使用 divide(BigDecimal,保留小数点后几位小数,舍入模式)
类型 | 说明 |
---|---|
static int ROUND_CEILING | 舍入模式向负无穷大舍入 |
static int ROUND_DOWN | 舍入模式向零舍入。 |
static int ROUND_FLOOR | 舍入模式向负无穷大舍入。 |
static int ROUND_HALF_DOWN | 四舍五入模式向“最近邻居”转弯,除非这两个邻居都是等距离的,在这种情况下,这是倒圆的。 |
static int ROUND_HALF_EVEN | 四舍五入模式向“最近邻居”转弯,除非两个邻居都是等距离的,在这种情况下,向着邻居方向转移。 |
static int ROUND_HALF_UP | 四舍五入模式向“最近邻居”转弯,除非两个邻居都是等距的,在这种情况下是圆括弧的。 |
static int ROUND_UNNECESSARY | 舍入模式来确定所请求的操作具有精确的结果,因此不需要舍入。 |
static int ROUND_UP | 舍入模式从零开始。 |
2.4 枚举
public enum Color {
/**
*
*/
RED("红色", 1), Green("绿色", 2);
/**
* 成员变量
*/
private String colorName;
private int colorIndex;
/**
* 构造方法
* @param colorName
* @param colorIndex
*/
private Color(String colorName, int colorIndex) {
this.colorName = colorName;
this.colorIndex = colorIndex;
}
/**
* get方法
* @param colorName
* @return
*/
public String getColorName(String colorName) {
return colorName;
}
/**
* set方法
* @return
*/
public int getColorIndex() {
return colorIndex;
}
/**
* 普通方法
* @param colorIndex
* @return
*/
public static String getColorName(int colorIndex) {
for (Color c : Color.values()) {
if(c.getColorIndex() == colorIndex) {
return c.colorName;
}
}
return null;
}
/**
* 覆盖方法(重写toString()方法)
*/
@Override
public String toString() {
return "Color-->" +
"colorName=" + colorName +
", colorIndex=" + colorIndex;
}
}
枚举的使用:
public class StartClass {
public static void main(String[] args) {
String colorName = Color.getColorName(2);
System.out.println("colorName => " + colorName); // colorName => 绿色
Color red = Color.RED;
System.out.println(red); // Color-->colorName=红色, colorIndex=1
}
}
枚举继承自 java.lang.Enum 类,Java不支持多继承,所以不能再继承其他类,但是可以实现其他接口方法
java中的 …
… 表示可变数组,数组长度可变,可以输入0个或多个参数
public class ParamTest {
public static void main(String[] args) {
ParamDeal();
ParamDeal("a");
ParamDeal("a", "b");
ParamDeal("a", "b", "c");
}
public static void ParamDeal(String... param) {
for (String s : param) {
System.out.println("s = " + s);
}
System.out.println("-------------------");
}
}
运行结果:
-------------------
s = a
-------------------
s = a
s = b
-------------------
s = a
s = b
s = c
-------------------
开发规范
浮点数的等值判断
基本数据类型不能用 == 进行比较
包装数据类型不能用 equal 方法判断
反例:
float a = 1.0f - 0.9f;
float b = 0.9f - 0.8f;
System.out.println(a == b); // false
Float c = 1.0f - 0.9f;
Float d = 0.9f - 0.8f;
System.out.println(c == d); // false
System.out.println(c.equals(d)); // false
正例:
public void floatTest() {
// 1. 指定一个误差范围,两个浮点数的插值在此范围之内,则认为是相等的
float a = 1.0f - 0.9f;
float b = 0.9f - 0.8f;
// 10 的 -6次方
float diff = 1e-6f;
if (Math.abs(a - b) < diff) {
System.out.println("true");
}
// 2. 使用 BigDecimal 定义值,再进行浮点数的运算操作
BigDecimal d = new BigDecimal("1.0");
BigDecimal e = new BigDecimal("0.9");
BigDecimal f = new BigDecimal("0.8");
BigDecimal x = d.subtract(e);
BigDecimal y = e.subtract(f);
/**
* BigDecimal 的等值比较应使用 compareTo() 方法,而不是 equal() 方法。
* equal() 方法会比较值和精度(1.0 与 1.00 返回结果为 false)
* 而 compareTo() 则会忽略精度
*/
if (x.compareTo(y) == 0) {
System.out.println("true");
}
}
BigDecimal 相关
禁止使用构造方法BigDecimal(double)的方式把double值转化为BigDecimal对象。
说明:BigDecimal(double)存在精度损失风险,在精确计算或值比较的场景中,可能会导致业务逻辑出现异常。如:BigDecimal g = new BigDecimal(0.1f); 实际的存储值为:0.100000001490116119384765625。
优先推荐入参为 String 的构造方法
,或使用 BigDecimal 的 valueOf() 方法
。此方法内部执行了 Double 的 toString,而 Double 的 toString 按 double 的实际能表达的精度对尾数进行了截断。
3. 运算符
3.1 算数运算符
算术运算符规则
整数运算:
- 如果两个操作数有一个为 long, 则结果也为 long。
- 没有 long 时,结果为 int。即使操作数全为 short,byte,结果也是 int。
浮点运算:
- 如果两个操作数有一个为 double,则结果为 double。
- 只有两个操作数都是 float,则结果才为 float。
取模运算:
- 其操作数可以为浮点数,一般使用整数,结果是“余数”,“余数”符号和左
- 边操作数相同,如:7%3=1,-7%3=-1,7%-3=1。
例:
public class test{
public static void main(String[] args){
//算术运算符中的取余符号变化规律
int a = 10;
int b = 3;
System.out.println(a%b);
System.out.println(-a%b);
}
}
1
-1
3.2 赋值运算符
注:拓展的赋值运算符隐含了强制类型转换
public class test{
public static void main(String[] args) {
//扩展的赋值运算符隐含了强制类型转换
short s = 20;
s += 10; // s =(short) (s + 10)
System.out.println(s);
}
}
30
public class test{
public static void main(String[] args) {
//扩展的赋值运算符隐含了强制类型转换
int a=3;
int b=4;
a+=b; //a=a+b
System.out.println("a="+a+"\nb="+b);
a=3;
a*=b+3; // 等同于a = a *( b + 3)=21 会将扩展赋值运算符后的表达式作为一个整体和左边进行运算
System.out.println("a="+a+"\nb="+b);
}
}
a=7
b=4
a=21
b=4
3.3 自增自减运算符
例1:
public class test{
public static void main(String[] args) {
/*
++ 自增
-- 自减
*/
int a = 5;
System.out.println(a++);//5 先取值 后运算
System.out.println(a);//6
System.out.println(++a);//7 先运算 后取值
}
}
5
6
7
例1:
public class test{
public static void main(String[] args) {
/*
++ 自增
-- 自减
a++ 先取值,后运算
++b 先运算,后取值
*/
int a = 5;
int b = a++ + 1;
System.out.println(a);// 6
System.out.println(b);// 6,此时a++ = 5
int c = 5;
int d = ++c + 1;
System.out.println(c);// 6
System.out.println(d);// 7
}
}
6
6
6
7
public class test{
public static void main(String[] args) {
/*
++ 自增
-- 自减
a++ 先取值,后运算
++b 先运算,后取值
*/
int x = 10;
int y = x++ + x++ + x++;
/*第一次运算x++为10,运算结束x=11;
第二次运算x++ + x++(x++为11),运算结束x=12
第三次运算x++ + x++ + x++(x++为12),运算结束后为13
*/
System.out.println(y); // y的值是多少?
System.out.println(x);
}
}
33
13
3.4 关系运算符
注:关系运算符的结果都是boolean类型,结果为true or false。
例:
public class test{
public static void main(String[] args) {
//关系运算符输出为boolean类型
int a = 10;
int b = 12;
boolean c = a != b;
System.out.println(c);
}
}
true
3.5 逻辑运算符
public class test{
public static void main(String[] args) {
//逻辑运算符:逻辑与&,同真为真,其余为假
int a = 10;
int b = 12;
boolean c = a != b & a > b;
System.out.println(c);
}
}
false
3.6 短路逻辑运算符
注:
逻辑与&:无论左边真假,左右都要执行。
短路与&&:如果左边为真,继续执行右边;如果左边为假,右边不执行。
逻辑或|:无论左边真假,右边都要执行。
短路或||:如果左边为加,继续执行右边;如果左边为真,右边不执行。
例:
public class test{
public static void main(String[] args) {
//逻辑与& 短路与&&
int a = 10;
int b = 12;
boolean c = a == b & a > ++b;
System.out.println(c);
System.out.println(b); //虽 a == b为假,但仍需执行a > ++b,故 b = 13
b = 12;
boolean c1 = a == b && a > ++b;
System.out.println(c1);
System.out.println(b); //虽 a == b为假,则不需执行a > ++b,故 b = 12,不变
}
}
false
13
false
12
3.7 位运算符
- 位运算符是在二进制下进行运算的,所以效率很高;原码,反码这些我也不太清楚,等我学会后面会单独写一篇。
&:按位与
负数的与运算
-2140814344
1. 将负数对应的相反数转换为二进制
2. 将二进制数取反(0 与 1 互换)
3. 将取反后的数 +1
4. 将负数对应的二进制数与其他数按位比较(同为1时为1,其他为0)
5. 将二进制转为十进制
流程:-2140814344
-> 0111 1111 1001 1010 0011 1100 0000 1000(相反数对应的二进制)
-> 1000 0000 0110 0101 1100 0011 1111 0111(二进制取反)
-> 1000 0000 0110 0101 1100 0011 1111 1000(取反后的数 +1)
-> 0000 0000 0000 0000 0000 0000 0111 1111(127 转为二进制)
-> 0000 0000 0000 0000 0000 0000 0111 1000(按位比较结果)
-> 120(二进制转为十进制)
注:
计算机中存储的是数字的二进制的补码。
正数的原码、反码、补码是一样的。
负数的、原码、反码除符号位,其余位按位取反(0变1, 变0)
补码:原码取反+1
位运算的执行效率是最高的
例:
public class test{
public static void main(String[] args) {
//位运算符,左移运算符<<,右移运算符>>
int a = 3 ;
int b = 2;
int c = 3 << 2;// 3 * 2 * 2 原理是将3转换为二进制数...0011,左移两位即为...1100,转换为十进制数为12
int d = 3 >> 2;//3/2/2 原理是将3转换为二进制数...0011,右移两位即为...0000,转换为十进制数为0
System.out.println(c);
System.out.println(d);
}
}
12
0
3.8 三元运算符
格式:关系表达式 ? 表达式1 : 表达式2
结果:当关系式1成立(true)时,则整个三元运算的结果为表达式1,否则为表达式2。
例1:
public class test{
public static void main(String[] args) {
//三元运算符
int a = 3 ;
int b = 2;
int c = a < b ? a+1 : ++b;
System.out.println(c);
}
}
3
例2:
public class test{
public static void main(String[] args){
/*
需求:一座寺庙里住着三个和尚,已知他们的身高分别为150cm、210cm、165cm,
请用程序实现获取这三个和尚的最高身高。
*/
int height1 = 150;
int height2 = 210;
int height3 = 165;
int Max_height = (height1 > height2 ? height1 : height2) > height3 ? (height1 > height2 ? height1 : height2): height3;
System.out.println("Max_height="+Max_height);
}
}
Max_height=210