java 目前属于甲骨文, 长期支持版本为 java8 和 java11, 主要学习JavaEE (Java Enterprise Edition) 企业版
java特性:
- 强类型 静态类型的语言
- 跨平台 --> 不同平台的JVM保证
- 解释性 --> 使用JVM解释字节码
JVM是一台虚拟的计算机,具有指令集并使用不同的存储区域。负责执行指令,管理数据、内存、寄存器
JDK(Java Development Kit)是什么?
JDK 是 Java 语言的软件开发工具包,关于JDK与JRE:
- JDK = JRE + java开发工具
- JRE = JVM + 核心类库
如果只需要运行开发好的
.class
文件, 只需要JRE即可
JDK的国内下载源,见:JDK下载
第一个程序创建一个Hello.java
文件,写入如下内容:
public class Hello {
public static void main(String[] args){
System.out.println("hello world");
}
}
-
文件名要与类名相同
-
定义方式
public class
和public static void main(){xxx}
-
要以
;
结尾 -
使用
javac Hello.java
编译java文件成Hello.class
(字节码)假如报错:
错误: 编码 GBK 的不可映射字符
,那是因为编码问题,只需要添加-encoding utf8
即可 -
使用
java Hello
运行程序(将字节码放到JVM中解释)
-
java源文件以
.java
为扩展名,源文件的基本组成部分为类 -
java应用程序的执行入口为
main
, 它有固定的写法:public static void main(String[] args){....}
-
java区分大小写
-
语句要以
;
结尾 -
一个源文件中最多只能有一个
public
类, 其他类不限public class Hello{ public static void main(String[] args){ System.out.println("hello 1"); } } // 其他的类 class Dog{ public static void main(String[] args){ System.out.println("hello dog"); } } class Cat{ public static void main(String[] args){ System.out.println("hello Cat"); } }
编译后会生成对应类的字节码如:
Dog.class
Cat.class
-
编写风格
有两种:行尾风格和次行风格
-
包名
多单词组成时,都小写且使用.
链接,如:aaa.bbb.ccc
-
类名 接口名
多单词组成时,使用大驼峰, 比如ShotGame
-
变量名 方法名 使用小驼峰, 比如
shotGame
-
常量名 全大写使用
_
连接,比如MAX_NUM
一般使用如下:
public class Test{
public static void main(String[] args){
System.out.println("张三\t李四\t王五"); // 制表符
System.out.println("你好\n世界"); // 回车
System.out.println("c:\\d"); // \
System.out.println("aaa\rbb"); // 换行会替换掉
System.out.println("aaa\r\bbb"); // 换行+回车会在下一行
}
}
注释
java的注释分
- 单行注释
public class Comment{ public static void main(String[] args){ // 单行注释 /* 多行注释 */ System.out.println("查看代码"); } }
- 多行注释
public class Comment{ public static void main(String[] args){ /* 多行注释 */ System.out.println("查看代码"); } }
- 文档注释
比较重要,文档注释可以被javadoc解析成网页,其写法有固定的格式。
使用命令:/** * 这个类演示了文档注释 * @author lczmx * @version 1.2 */ public class Comment{ public static void main(String[] args){ System.out.println("查看代码"); } }
javadoc Comment.java -d ./docs -encoding utf8 -author -version
即可解析成网页
上面使用的是author
和version
这两个标签,更多的标签见:Java 文档注释
打开./docs/index.html
即可查看文档
看文档时需要注意java类的组织形式:
有两种方式:
public class Var{
public static void main(String[] args){
// 声明再赋值
int a;
a = 1;
// 声明并赋值
int b = 3;
System.out.println("a=" + a + "b=" + b);
}
}
+号的使用
使用+
时遵循如下规则:
- 两边为数值,加法运算
- 一边为字符串,拼接
public class Plus{
public static void main(String[] args){
System.out.println(100 + 98);
System.out.println("100" + 98);
System.out.println(100 + 3 + "hello");
System.out.println("hello" + 100 + 3);
/*
198
10098
103hello
hello1003
*/
}
}
基本数据类型
注意, java的字符串不是基本数据类型,它是一个对象
使用例子:
public class Type{
public static void main(String[] args) {
// 整形
byte a = 1; // -128 127 2^7
short b = 22; // -32768 32767
int c = 123455; // -2147483648 2147483647
long d = 123232323L; // -9223372036854775808 9223372036854775807
// 形如1234 默认为int,可以手动指明为long类型
// 不指明时会自动转换
// 浮点型
float f1 = 1.1234F;
// Java中的浮点字面值默认为双精度。要指定浮点字面值,必须在该常量后面附加一个 F 或 f 。
double f2 = 1.231;
// 字符
char e = '六'; // !!!! 注意为单引号,内部就是一个数字, 所以可以 char e = 97 这样定义
boolean f = true; // or false
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
System.out.println(f1);
System.out.println(f2);
System.out.println(e);
System.out.println(f);
}
}
关于浮点数的运算与比较,有点特殊:
public class Float{
public static void main (String[] args) {
// 默认1.1为双精度浮点型, 需要指定F
float f1 = 1.23456789F;
double f2 = 1.23456789;
System.out.println(f1); // 精度缺失
System.out.println(f2); // 精度可以保存
// 科学计数法
double f3 = 1.23E2; // 1.23 * 10^2
double f4 = 1.23E-2; // 1.23 * 10^-2
System.out.println(f3); // 123.0
System.out.println(f4); // 0.0123
// 比较浮点数
// 由于计算后的浮点数在内存中为一个近似值,所以不能直接比较
// 应该相减,小于一个固定范围视为相等(范围根据业务来)
double money1 = 1.2;
double money2 = 1.2;
// 可以执行
if ( money1 == money2 ) {
System.out.println("money1与money2 金额相等!");
}
double money3;
money3 = 0.4 * 3; // 实质上可能是1.200000000001
// 计算相差绝对值,是否小于固定范围
if ( Math.abs(money1 - money3) <= 0.001 ) {
System.out.printlnk("money1与money3 金额相等!");
}
}
}
这是因为浮点数不直接存放数字,而是存放:符号位 + 指数位 + 尾数位
而尾数部分可能丢失,造成精度损失(所以浮点数都是近似值)
关于字符类型,也要补充一下, 主要是编码方式的区别:
public class CharDetail{
public static void main(String[] args){
// 一般使用
char c1 = 'a';
char c2 = 98;
char c3 = 'a' + 2;
// 输出
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
// =====> 输出数字
System.out.println((int)c1);
// 1. Char两个字符表示, 对应的编码方式为unicode
// 2. Char在内部以数字存储:
// a -(通过编码方式)-> 97 -> 内存
// 3. 读取的时候会,自动将数字装换成编码方式中对应的字符
// 内存 -> 97 -(通过编码方式)-> a
// 补充一下字符编码
// ASCII 8bit表示,128个字符(0~127)
// unicode 中英文都为2字节
// UTF-8 (1~6个字节) 大小可动态变化,英文1字节 中文3字节
// ----------- 一个字符(即'a'或'中')可以有多个字节
}
}
类型转换字符集中只规定了 字符的代码值 并未规定具体如何存储,编码方式解决了字符在计算机中 如何存储 的问题。
即不同数据类型如何转换
自动类型转换低精度可以自动向高精度转换
有两条路线:
// char -> int -> long -> float -> double
// 2 4 8 4 8
// byte -> short -> int -> long -> float -> double
// 1 2 4 8 4 8
这里有一个问题: float 4个字节可以存放 long 8个字节?
主要原因是float/double
不是直接存储数值: 浮点数的32位不是简单的直接表示大小,而是按照一定的标准分配的。其中
- 第1位,符号位。
- 接下来的8位,指数域。
- 剩下的23位,小数域,M的取值范围为
[1,2)或[0,1)
。
也就是说,浮点数在内存中的二进制值不是直接转换为十进制数值的,而是按照上述公式计算而来, 通过这个公式,虽然只用到了4个字节,但是浮点数却比长整型的最大值要大。
一般使用的规则:
- 低精度可以转换成高精度, 反之不行
- 多种类型运算时,先转化成最大的
- ( byte, short ) 不可以与 char 之间相互转化
- byte short 和 char 之间 虽然不能转化,但是这三者之间可以进行运算,结果提升为int,自身运算也会提升
- boolean 不转化 为数字
// 类型转换
public class AutoConvert{
public static void main(String[] args) {
// 1. ======= 低精度可以转换成高精度
// char -> int -> long -> float -> double
// 2 4 8 4 8
// byte -> short -> int -> long -> float -> double
// 1 2 4 8 4 8
int a = 'a';
double b = 80;
System.out.println(a); // 97
System.out.println(b); // 80.0
// 2. =========== 多种类型运算时,先转化成最大的
int a2 = 10;
// float b2 = a2 + 1.1; // 不可以,因为1.1为double
double b2 = a2 + 1.1;
System.out.println(b2);
// 3. =========== ( byte, short ) 不可以与 char 之间相互转化
// 按照我的理解,byte 和 short 虽然有1字节和2字节大小,但是为有符号的数字
// 所以不能让byte short 和 char之间进行转化
/*
byte c3 = 1;
short s3 = 2;
char char3 = c3;
*/
// 4. =========== 低精度往高精度转化,不行
// int a4 = 1.1;
// !! 但是 byte short 会先判断数值大小,才赋值,所以可以直接使用 1 2 3........
byte b4 = 1;
// !! 如果用int的话不行, 它先判断类型
int ab4 = 2;
// byte b44 = ab4;
short s4 = 1;
// 5. byte short 和 char 之间 虽然不能转化,但是这三者之间可以进行运算,结果提升为int
byte b5 = 2;
short s5 = 1;
char c5 = 11;
int result5 = b5 + s5; // byte + short
System.out.println(result5); // 3
int result6 = b5 + c5; // byte + char;
System.out.println(result6); // 13
int result7 = s5 + c5; // short + char;
System.out.println(result7); // 12
// !!! 与自身运算也是int
int result8 = b5 + b5; // byte + byte => int
// short char 也是这样
System.out.println(result8); // 4
byte num1 = 1;
short num2 = 2;
int num3 = 123;
float num4 = 1.234F;
double num5 = num1 + num2 + num3 + num4; // => float 转化成 double
System.out.println(num5);
// 6. ========= boolean 不转化 为数字
// !! 就行强制转化也不行
/*
boolean boo6 = true;
int i6 = (int)boo5;
int i6 = boo5;
*/
}
}
强制类型转换
我们可以对数值进行强制转化,不过强制类型转化 会丢失精度 或 数据溢出, 取舍权衡需要考虑好
一般的使用形式: (type)xx
// 高精度 -> 低精度:需要强制类型转化
public class ForceConvert{
public static void main(String[] args){
int a = (int)2201.2; // 精度丢失
byte b = (byte)a; // 数据溢出
System.out.println(a); // 2201
System.out.println(b); // -103 数据溢出了
System.out.println( (byte)127 ); // 不超出范围则不会溢出 (byte 1个字节 -127 ~ 127)
}
}
与字符串的相互转换
即如何将其他类型转换成字符串和将字符串转化成其他类型
前者需要只需要+
空字符串即可
后者需要 通过基本类型的 包装类 调用 parseXxx方法即可
需要注意的是,字符串转字符类型,使用的是
charAt(index)
方法
public class ToString{
public static void main(String[] args){
// 其他类型 => String
char c1 = 97;
int i1 = 2;
float f1 = 3.14F;
boolean b1 = true;
String s1 = c1 + "";
String s2 = i1 + "";
String s3 = f1 + "";
String s4 = b1 + "";
// a 2 3.14 true
System.out.println( " " + s1 + " " + s2 + " " + s3 + " " + s4 );
}
}
class ToOther{
public static void main( String[] args ){
// String => 其他类型
// !! 通过基本类型的 包装类 调用 parseXxx方法即可
// !! 属于面向对象内容
// 注意Integer的写法
String s1 = "123";
int num1 = Integer.parseInt(s1);
float num2 = Float.parseFloat(s1);
short num3 = Short.parseShort(s1);
// 其他的类推
boolean b = Boolean.parseBoolean("true");
System.out.println(num1);
System.out.println(num2);
System.out.println(num3);
System.out.println(b);
// !! 取字符
System.out.println(s1.charAt(0));
// !! 注意:可能不一定装换成功, 需要异常处理
}
}
运算符
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。
算术运算符算术运算符 是对数值类型的变量进行运算的运算符
+
正号
+7
7
-
负号
b=11; -b
-11
+
加
9 + 9
18
-
减
10 - 8
2
*
乘
7 * 8
56
/
除
9 / 9
1
%
取模(余数)
11%9
2
++
自增
a=2;b=++a;
a = 3;b=3
--
自减
a=2;b=--a
a=1;b=1;
+
字符串相加
"lcz" + "mx"
“lczmx”
需要特别注意
++
和--
, 它们在给其他变量赋值时,在原变量的前后的结果是不一样的,看下面的例子
使用例子:
public class ArithmeticOperator{
public static void main(String[] args){
// 注意混合运算后的结果类型
// +
int a = 2;
int b = 1;
System.out.println(a + b); // 3
// -
System.out.println(a - b); // 1
// *
System.out.println(a * b); // 2
// /
System.out.println(a / b); // 2
// ======= %
// !! 取模运算公式
// a % b = a - a / b * b
System.out.println(10 % 3); // 1
System.out.println(-10 % 3); // -1
System.out.println(10 % -3); // 1
System.out.println(-10 % -3); // -1
// 总结一下:
/*
1. 正 % 正 = 正
2. 负 % 正 = 负
3. 正 % 负 = 正
4. 负 % 负 = 负
即 第一个数为负数时,结果为负数
!! 假如a为double时会:
a % b = a - (int)a / b * b
*/
// ++ 和 --
// i = j++ i = j-- : 先赋值再操作
// i = ++j i = --j : 先操作再赋值
// 总结,看变量在前面还是运算符在前面
// 变量在前,则先取变量的值,则运算
// 运算符在前,则先运算,再取值
int i = 10;
int j = i++;
System.out.println("i++: i = " + i + " j = " + j);
i = 10;
j = ++i;
System.out.println("++i: i = " + i + " j = " + j);
// !! 自己使用++ -- 赋值时的规则
// 会引用一个临时变量,保存数据
int count = 1;
count = count++;
// 1. 返回count使用临时变量保存,即 temp = count
// 2. 运算++, 即 count = count + 1
// 3. 赋值给count, 用的是temp的数据: count = temp
System.out.println(count); // 1
count = ++count;
// 1. 返回++使用临时变量保存
// count = count + 1
// temp = count
// 2. 赋值给count,即 count = temp
System.out.println(count); // 2
}
}
关系运算符
关系运算符的结果都是boolean型,即true
或者false
使用例子如下:
public class RelationalOperator{
public static void main(String[] args){
System.out.println(1 == 1);
System.out.println(1 != 1);
System.out.println(1 < 2);
System.out.println(1 > 2);
System.out.println(1 <= 2);
System.out.println(1 >= 2);
boolean isInstance = "lczmx" instanceof String;
System.out.println("\"lczmx\"为String子类: " + isInstance);
}
}
逻辑运算符
逻辑运算符有以下几种:
&
&&
逻辑与 短路与|
||
逻辑或 短路或!
取反^
逻辑异或
解释一下:
- 与指的是两边同时为
true
时, 才为true
- 或指的是有一边为
true
时, 则为true
- 短路指的是不满足条件的立即返回 如(
false && true
), 看到false
就跳出了,不看true
,而逻辑则会全部看完 - 取反即
true
变flase
,false
变true
- 逻辑异或指的是两边布尔值不同时为true, 否则为false, 如(
false^ true
=>true
)
重点关注: 逻辑与 短路与 逻辑或 短路或,举个例子:
public class LogicOperator{
public static void main(String[] args){
int a = 3;
// 短路
if (a < 2 && a++ > 10){}
// 结果: a = 3
System.out.println(a);
// 逻辑
if (a < 2 & a++ > 10){}
// 结果: a = 4
System.out.println(a);
}
}
赋值运算符
比较简单:=
+=
-=
*=
/=
%=
使用例子:
public class AssignOperator{
public static void main(String[] args) {
int n1 = 10;
n1 += 4; // n1 = n1 + 4;
System.out.println(n1); // 14
n1 /= 3; // n1 = n1 /3;
System.out.println(n1); // 4
byte b = 3;
b += 2; // 等价于 b = (byte)(b + 2);
}
}
三元运算符
相当于if-else
的简写版, 格式:
int a = 10;
int b = 99;
int result = a > b ? a++ : b--;
表达式成立时, 返回的第一个a++
, 否返回第二个b--
位运算符需要主要返回类型是否为接收结果的类型
7个位运算符
&
按位与|
按位或^
按位异或~
按位取反>>
算术右移 低位溢出, 符号位不变 并用符号位补充溢出的高位<<
算术左移 符号位不变 低位补0>>>
无符号右移 低位溢出 到位补0
注意: 没有
<<<
运算时注意转成补码, 取结果时注意转成原码
使用例子:
public class BitOperator{
public static void main(String[] args){
// 2 & 3
/*
2的原码 00000000 00000000 00000000 00000010
3的原码 00000000 00000000 00000000 00000011
补码相同
& 00000000 00000000 00000000 00000010
补码为正,原码相同
2
*/
System.out.println(2 & 3);
// ~-2
/*
-2的原码 10000000 00000000 00000000 00000010
反码 11111111 11111111 11111111 11111101
补码 11111111 11111111 11111111 11111110
~ 00000000 00000000 00000000 00000001
补码为正,原码相同
1
*/
System.out.println(~-2);
// ~2
/*
2的原码 00000000 00000000 00000000 00000010
补码相同
~ 11111111 11111111 11111111 11111101
结果反码
11111111 11111111 11111111 11111100
结果原码 10000000 00000000 00000000 00000011
-3
*/
System.out.println(~2);
// 2|3
/*
2的原码 00000000 00000000 00000000 00000010
3的原码 00000000 00000000 00000000 00000011
都为正数 补码相同
| 00000000 00000000 00000000 00000011
结果为正数
3
*/
System.out.println(2|3);
// 2^3
/*
2的原码 00000000 00000000 00000000 00000010
3的原码 00000000 00000000 00000000 00000011
都为正数 补码相同
| 00000000 00000000 00000000 00000001
结果为正数
1
*/
System.out.println(2^3);
// 1 >> 2
System.out.println(1 >> 2);
/*
00000001 => 000000000 => 1/2/2 = 0
*/
// 1 << 2
/*
00000001 => 000000100 => 1*2*2 = 4
*/
System.out.println(1 << 2);
// 4 << 3
/*
00000100
00100000
=> 32
=> 4 * 2 * 2 * 2 = 32
!! 即我们无需写出位,可以直接*2或/2, 取整即可
*/
System.out.println(4 << 3);
}
}
运算符优先级
如下图
输入使用Scanner类
, 输出使用System.out.println
或System.out.print
使用例子:
// 1. 导入, 简单的文本扫描器
import java.util.Scanner;
public class ScannerIn{
public static void main(String[] args) {
// 2. 创建一个对象实例
// 注意类型
Scanner s = new Scanner(System.in);
// 3. 打印提示
System.out.println("请输入名字");
// 4. 使用next等方法,接收用户输入
String name = s.next(); // 字符串
System.out.println("请输入年龄");
int age = s.nextInt(); // int
System.out.println("请输入工资");
double salary = s.nextDouble(); // double
// !! 输入类型不对时,会报错
System.out.println("用户信息如下:");
System.out.println("name=" + name + "; age=" + age + "; salary=" + salary);
// 5. 这些方法,可以看文档:https://www.matools.com/file/manual/jdk_api_1.8_google/java/util/Scanner.html
}
}
进制 定义方式
System.out.print
不会自动换行
通过数字前面的标记,确定进制,默认十进制
public class BinaryTest{
public static void main(String[] args) {
// 二进制
int num1 = 0B10; // or 0b1234
// 八进制
int num2 = 010; // 0开头
// 十进制
int num3 = 10;
// 十六进制
int num4 = 0X10; // or 0xa
System.out.println(num1); // 2
System.out.println(num2); // 8
System.out.println(num3); // 10
System.out.println(num4); // 16
}
}
十进制转其他进制
要点:
- 将该数不断除以进制数, 直到商为0
- 将每一步的余数倒过来
public class DecimalToOther{
public static void main(String[] args){
int num1 = 123; // -> 2
/*
123 / 2 = 61 余 1
61 / 2 = 30 余 1
30 / 2 = 15 余 0
15 / 2 = 7 余 1
7 / 2 = 3 余 1
3 / 2 = 1 余 1
1
*/
// => 0b01111011
// 记得补全八位
int num2 = 679; // -> 8
/*
679 / 8 = 84 余 7
84 / 8 = 10 余 4
10 / 8 = 1 余 2
1
*/
// => 01247
int num3 = 8912; // ->16
/*
8912 / 16 = 557 余 0
557 / 16 = 34 余 d (13)
34 / 16 = 2 余 2
2
*/
// => 0X22E0
}
}
其他进制转十进制
规则:从最低为开始(右边),将每位上的数据提取出来,乘以进制的(位数-1)次方
public class OtherToDecimal{
int num1 = 0b110001100;
// 0 * 2^0 + 0 * 2^1 + 1 * 2^2 + 1 * 2^3 + 0 * 2^4 + 0 * 2^5 + 0 * 2^6 + 1*2^7 + 1*2^8
// = 0 + 0 + 4 + 8 + 0 + 0 + 0 + 128 + 256
// = 396
int num2 = 02456;
// 6 * 8^0 + 5 * 8^1 + 4 * 8^2 + 2 * 8^3
// = 6 + 40 + 256 + 1024
// = 1326
int num3 = 0xa45;
// 5 * 16^0 + 4 * 16^1 + 10 * 16^2
// = 5 + 64 + 2560
// = 2629
}
二进制转八/十六进制
要点:
- 分组(3 位 或 4 位一组)转换成10进制
- 合并即可
注意二进制与十进制的对应关系:
1 1 1 1 1 1
32 16 8 4 2 1
这样就可以很快得出答案了,如:111 => 1 + 2 + 4 = 7
使用例子:
public class BinaryToOther{
public static void main(String[] args){
int num1 = 0b11100101; // -> 8
/*
11 100 101
3 4 5
=>0345
*/
int num2 = 0b1110010110; // -> 16
/*
11 1001 0110
3 9 6
=>0x396
*/
}
}
八/十六进制转二进制
要点:
- 将一位数 转换为(3 位 或 4 位一组二进制)
- 合并即可
注意补全
使用例子:
public class OtherToBinary{
public static void main(String[] args){
int num1 = 01230;
/*
1230
1(001) 2(010) 3(011) 0(000)
=> 0b0000001010011000
*/
int num2 = 0xAB29
/*
AB29
A(1010) B(1011) 2(0010) 9(1001)
数值太大时 只需要让8-当前值,等到小的值即可
=> 0b1010101100101001
*/
}
}
原码反码补码
这个问题比较重要
主要遵循如下规则:
- 二进制的最高位是符号位:0表示正数,1表示负数 (将1倒过来不就是
-
了吗) - 正数的原码,反码,补码都一样(三码合一)
- 负数的反码=它的原码符号位不变,其它位取反 (0->1,1->0)
- 负数的补码=它的反码 + 1,即 负数的反码=负数的补码 - 1
- 0的反码,补码都是0
- java没有无符号数,换言之,java中的数都是有符号的
- 在计算机运算的时候,都是以补码的方式来运算的 (所以需要先转成补码)
- 当我们看运算结果的时候,要看他的原码(结果是补码,需要转成原码)
一般来说,流程控制用三种:
- 顺序控制 一般的代码流程,从上到下执行
- 分支控制 一个或多个分支执行
- 循环控制 可以让代码重复执行
举个例子:
做个出票系统:根据淡旺季的月份和年龄,打印票价
- 4-10月旺季:
- 成人(18-60):60
- 儿童(<18):半价
- 老人(>60):1/3
- 淡季:
- 成人(18-60):40
- 其他:20
import java.util.Scanner;
public class TicketingSytem{
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("月份");
int month = s.nextInt();
System.out.println("年龄");
byte yearOld = s.nextByte();
if (month >= 4 && month <= 10){
int price = 60;
if (yearOld < 18){
System.out.println(price / 2);
}else if(yearOld > 60){
System.out.println(price / 3);
}else{
System.out.println(price);
}
}else{
if (yearOld > 18 && yearOld < 60){
System.out.println(40);
}else{
System.out.println(20);
}
}
}
}
switch分支赋值作为条件时,看赋值后的变量,如
boolen a= false
if(a=true)
=> 这样是可以执行的
格式:
switch (c){
case 'a':
System.out.println("星期一");
break;
default :
System.out.println("未知");
break;
}
注意事项:
- 表达式数据类型,应和case后的常量类型一致,或者是可以自动转成可以相互比较的类型,比如输入的是字符 而常量是int
- switch(表达式)中表达式的返回值必须是:(byte,short,int,char,enum,String)
- case子句中的值必须是常量,而不能是变量
- default子句是可选的,当没有匹配的case时,执行default
- break语句用来在执行完一个case分支后使程序跳出switch语句块;如果没有写break,程序会顺序执行到switch结尾(即不会判断case)
使用例子:
/*
1.
使用switch把小写类型的char型转为大写(键盘输入)。只转换a,b,c,d,e.
其它的输出"other"。
2.
对学生成绩大于60分的,输出"合格”。低于60分的,输出"不合格”。(注:输入
的成绩不能大于100),提示成绩/60
3.
根据用于指定月份,打印该月份所属的季节。3,4,5春季6,7,8夏季9,10,11
秋季12,1,2冬季[课堂练习,提示使用穿透]
*/
import java.util.Scanner;
public class SwitchExercise{
public static void main(String[] args){
// 1
System.out.println("char>>>");
Scanner scanner = new Scanner(System.in);
char c = scanner.next().charAt(0);
switch (c){
case 'a':
System.out.println('A');
break;
case 'b':
System.out.println('B');
break;
case 'c':
System.out.println('C');
break;
case 'd':
System.out.println('D');
break;
case 'e':
System.out.println('E');
break;
default:
System.out.println("other");
break;
}
// 2
System.out.println("成绩>>>");
double score = scanner.nextDouble();
// [60, 100] => /60 = 1;
// [0, 60) => /60 = 0;
switch ( (int)score / 60 ){
case 1:
System.out.println("合格");
break;
case 0:
System.out.println("不合格");
break;
default:
System.out.println("异常数据");
break;
}
// 3
System.out.println("月份>>>");
int month = scanner.nextInt();
switch (month){
case 3:
case 4:
case 5:
System.out.println("春季");
break;
case 6:
case 7:
case 8:
System.out.println("夏季");
break;
case 9:
case 10:
case 11:
System.out.println("秋季");
break;
case 12:
case 1:
case 2:
System.out.println("冬季");
break;
}
}
}
循环控制
for循环
一般使用例子:
public class For {
public static void main(String[] args){
// 1.打印1~100之间所有是9的倍数的整数,统计个数及总和
int sum = 0, count = 0;
int start = 1, end = 100;
int t = 9; // 倍数
for (int i = start; i <= end; i++){
if (i % t == 0){
sum += i;
count++;
// 81 90 99
// 9 10 11
}
}
System.out.println("sum: " + sum + " count: " + count);
//打印
/*
0 + 5 = 5
1 + 4 = 5
2 + 3 = 5
3 + 2 = 5
4 + 1 = 5
5 + 0 = 5
*/
int total = 5;
for (int i=0; i<= total; i++){
int temp = total - i;
System.out.println(i + " + " + temp + " = " + total);
}
}
}
注意:
- 循环内部语句只有一天是,可以省略
{}
, 但不建议使用 - 多个条件可以使用
,
隔开,如if(int i=0,j=0; i<count; i++, j+=2)
- 我们可以省略初始化条件和变量迭代, 灵活使用,如
for( ; i<= 10 ; )
- 还可以全部省略,变成死循环,如
for(;;)
关于增强for, 是一种简化迭代器书写方式
使用例子:
public class Demo{
public static void main(String[] args){
int arr[] = {1,2,3};
/**
*增强for
*/
for(int num : arr){
System.out.println(num);
}
}
}
while循环只适合取数据,不能更改数据
只用于数组,或实现Iterable接口的集合类上;set,list
使用格式:
while (循环条件) {
循环体(语句);
循环变量迭代;
}
使用例子:
public class While{
public static void main(String[] args){
/*
1.打印1一100之间所有能被3整除的数
2.打印40一200之间所有的偶数
*/
int end1 = 100, end2 = 200;
int start1 = 1, start2 = 40;
int t1 = 3;
int t2 = 2;
while (start1 <= end1){
if (start1 % t1 == 0){
System.out.println(start1);
}
start1++;
}
while (start2 <= end2){
if (start2 % t2 == 0){
System.out.println(start2);
}
start2++;
}
}
}
doWhile循环
基本使用:
do{
循环体(语句);
循环变量迭代;
}while(循环条件);
- 先执行在判断,即至少执行一次
- while后面有
;
流程图:
使用例子:
import java.util.Scanner;
public class DoWhile{
public static void main(String[] args){
// 一般使用
// !! 至少会执行一次
// ! 不要忘记while后面的 ';' 了
int c = 0;
do {
System.out.println("lczmx " + c);
c++;
}while(c > 10);
// 统计1 - 200之间能被5整除但不能被3整除的个数
byte num1 = 5;
byte num2 = 3;
int i = 1;
int count = 0;
do {
if(i % num1 == 0 && i % num2 != 0){
count++;
}
i++;
}while(i<=200);
System.out.println("count " + count);
// 如果李三不还钱,打到张三说还钱为止
Scanner scanner = new Scanner(System.in);
char input;
do{
System.out.println("打!!\n还钱? y or n >>>");
input = scanner.next().charAt(0);
}while(input != 'y');
}
}
break和continue
- break跳出当前循环
- continue跳过本次循环
它们都可以指定Label,跳到对应的俄循环中
默认是当前的循环
使用例子:
lable1:
for (int j = 0; j < 4; j++) {
lable2:
for (int i = 0; i<10;i++) {
if(i == 2){
break lable1
}
}
}
同理,continue
也可以像上面那样操作
本文根据韩顺平 零基础30天学会Java视频整理而来