我是灼灼,一只初学Java的大一金渐层。
向往余秀华和狄兰·托马斯的疯狂,时常沉溺于将情感以诗相寄;追逐过王尔德、王小波的文字,后陷于毛姆和斯蒂芬·金不可自拔;热爱文学的浪潮,白日梦到底却总在现实里清醒;艳羡平静又极度渴盼奔跑的力量。
欢迎与我交流鸭· QQ:1517526827;
个人博客:https://blog.csdn.net/weixin_52777510?spm=1001.2101.3001.5343
Java笔记正在连载中,欢迎来其他内容逛逛哟~
相关内容如下:
【连载1】Java笔记——基本结构与流程控制
【连载2】Java笔记——数组操作
【连载3】Java笔记——面向对象编程
【连载4】Java笔记——Java核心类
【连载5】Java笔记——异常处理
【连载6】Java笔记——反射和注解
【连载7】Java笔记——泛型
【连载8】Java笔记——集合
【连载9】MySQL学习笔记
【连载10】JDBC学习笔记
【连载11】Git和GitHub的使用笔记
笔记内容来源于廖雪峰官方博客,菜鸟教程!膜拜~
CATALOGUE——>
第1章.Java简介
1.1Java是应用最广泛的编程语言
1.2Java语言的市场
1.3Java简介
1.4Java学习路线图
第2章.Java程序基本结构
Java基础语法
2.1Java程序基本结构
2.2Java变量和数据类型
2.3各种运算
第3章.流程控制
3.1输入和输出
3.2if语句
3.3switch多重判断
3.4while循环
3.5do-while循环
3.6for循环
3.7break和continue
1)Java是基于JVM虚拟机的跨平台语言,一次编写,到处运行;
2)Java程序易于编写,而且有内置垃圾收集,不必考虑内存管理;
3)Java虚拟机拥有工业级的稳定性和高度优化的性能,且经过了长时期的考验;
4)Java拥有最广泛的开源社区支持,各种高质量组件随时可用。
1)互联网和企业应用,这是Java EE的长期优势和市场地位;
2)大数据平台,主要有[Hadoop](Apache Hadoop_360百科 (so.com))、[Spark](SPARK_360百科 (so.com))、Flink等,他们都是Java或[Scala](scala_360百科 (so.com))(一种运行于JVM的编程语言)开发的;
3)Android移动平台。
这意味着Java拥有最广泛的就业市场。
以下内容来自360百科.
【hadoop】Hadoop是一个由Apache基金会所开发的分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。
Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性的特点,并且设计用来部署在低廉的硬件上;而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。
Hadoop的框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数据提供了存储,而MapReduce则为海量的数据提供了计算。
【MapReduce】MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算。概念"Map(映射)“和"Reduce(化简)”,和他们的主要思想,都是从函数式编程语言里借来的,还有从矢量编程语言里借来的特性。他极大地方便了编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。当前的软件实现是指定一个Map(映射)函数,用来把一组键值对映射成一组新的键值对,指定并发的Reduce(化简)函数,用来保证所有映射的键值对中的每一个共享相同的键组。基本信息如下
- 本质
一种编程模型- 用途
大规模数据集的并行运算- 特点
分布可靠- 应用
大规模的算法图形处理、文字处理- 功能
数据划分和计算任务调度- 思想来源
Google的几篇论文【Spark】Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎。Spark是UC Berkeley AMP lab (加州大学伯克利分校的AMP实验室)所开源的类Hadoop MapReduce的通用并行框架,Spark,拥有Hadoop MapReduce所具有的优点;但不同于MapReduce的是——Job中间输出结果可以保存在内存中,从而不再需要读写HDFS,因此Spark能更好地适用于数据挖掘与机器学习等需要迭代的MapReduce的算法。
Spark 是一种与 Hadoop 相似的开源集群计算环境,但是两者之间还存在一些不同之处,这些有用的不同之处使 Spark 在某些工作负载方面表现得更加优越,换句话说,Spark 启用了内存分布数据集,除了能够提供交互式查询外,它还可以优化迭代工作负载。
Spark 是在 Scala 语言中实现的,它将 Scala 用作其应用程序框架。与 Hadoop 不同,Spark 和 Scala 能够紧密集成,其中的 Scala 可以像操作本地集合对象一样轻松地操作分布式数据集。
尽管创建 Spark 是为了支持分布式数据集上的迭代作业,但是实际上它是对 Hadoop 的补充,可以在 Hadoop 文件系统中并行运行。通过名为 Mesos 的第三方集群框架可以支持此行为。Spark 由加州大学伯克利分校 AMP 实验室 (Algorithms, Machines, and People Lab) 开发,可用来构建大型的、低延迟的数据分析应用程序。
【Flink】Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。Flink以数据并行和流水线方式执行任意流数据程序,Flink的流水线运行时系统可以执行批处理和流处理程序。此外,Flink的运行时本身也支持迭代算法的执行。
【Scala】Scala是一门多范式的编程语言,一种类似java的编程语言 ,设计初衷是实现可伸缩的语言 、并集成面向对象编程和函数式编程的各种特性。
* 面向对象风格* 函数式风格
* 更高层的并发模型
* 轻量级的函数语法
o 高阶
o 嵌套
o 局部套用(Currying)
o 匿名
* 与XML集成
o 可在Scala程序中直接书写XML
o 可将XML转换成Scala类
* 与Java无缝地互操作
Java最早是由SUN公司(已被Oracle收购)的詹姆斯·高斯林(高司令,人称Java之父)在上个世纪90年代初开发的一种编程语言,最初被命名为Oak,目标是针对小型家电设备的嵌入式应用,结果市场没啥反响。谁料到互联网的崛起,让Oak重新焕发了生机,于是SUN公司改造了Oak,在1995年以Java的名称正式发布,原因是Oak已经被人注册了,因此SUN注册了Java这个商标。随着互联网的高速发展,Java逐渐成为最重要的网络编程语言。
Java介于编译型语言和解释型语言之间。编译型语言如C、C++,代码是直接编译成机器码执行,但是不同的平台(x86、ARM等)CPU的指令集不同,因此,需要编译出每一种平台的对应机器码。解释型语言如Python、Ruby没有这个问题,可以由解释器直接加载源码然后运行,代价是运行效率太低。而Java是将代码编译成一种“字节码”,它类似于抽象的CPU指令,然后,针对不同平台编写虚拟机,不同平台的虚拟机负责加载字节码并执行,这样就实现了“一次编写,到处运行”的效果。当然,这是针对Java开发者而言。对于虚拟机,需要为每个平台分别开发。为了保证不同平台、不同公司开发的虚拟机都能正确执行Java字节码,SUN公司制定了一系列的Java虚拟机规范。从实践的角度看,JVM的兼容性做得非常好,低版本的Java字节码完全可以正常运行在高版本的JVM上。
SUN给Java分出了三个不同版本:
这三者之间的关系:
┌───────────────────────────┐
│Java EE │
│ ┌────────────────────┐ │
│ │Java SE │ │
│ │ ┌─────────────┐ │ │
│ │ │ Java ME │ │ │
│ │ └─────────────┘ │ │
│ └────────────────────┘ │
└───────────────────────────┘
简单来说,Java SE就是标准版,包含标准的JVM和标准库,而Java EE是企业版,它只是在Java SE的基础上加上了大量的API和库,以便方便开发Web应用、数据库、消息服务等,Java EE的应用使用的虚拟机和Java SE完全相同。
/*Java ME就和Java SE不同,它是一个针对嵌入式设备的“瘦身版”,Java SE的标准库无法在Java ME上使用,Java ME的虚拟机也是“瘦身版”。
毫无疑问,Java SE是整个Java平台的核心,而Java EE是进一步学习Web应用所必须的。我们熟悉的Spring等框架都是Java EE开源生态系统的一部分。不幸的是,Java ME从来没有真正流行起来,反而是Android开发成为了移动平台的标准之一,因此,没有特殊需求,不建议学习Java ME。*/
【x86】X86是由Intel推出的一种复杂指令集,用于控制芯片的运行的程序,现在X86已经广泛运用到了家用PC领域。
基本信息
中文名
Intel x86
适用范围
芯片处理器
制造商
Intel
属 性
芯片运行指令集
应用行业
计算机硬件制造
【ARM】ARM处理器是Acorn计算机有限公司面向低预算市场设计的第一款RISC微处理器。更早称作Acorn RISC Machine。ARM处理器本身是32位设计,但也配备16位指令集,一般来讲比等价32位代码节省达35%,却能保留32位系统的所有优势。
【Ruby】一种简单快捷的面向对象(面向对象程序设计)脚本语言,在20世纪90年代由日本人松本行弘(Yukihiro Matsumoto)开发,遵守GPL协议和Ruby License。它的灵感与特性来自于 Perl、Smalltalk、Eiffel、Ada以及 Lisp 语言。由 Ruby 语言本身还发展出了JRuby(Java平台)、IronRuby(.NET平台)等其他平台的 Ruby 语言替代品。Ruby的作者于1993年2月24日开始编写Ruby,直至1995年12月才正式公开发布于fj(新闻组)。因为Perl发音与6月诞生石pearl(珍珠)相同,因此Ruby以7月诞生石ruby(红宝石)命名。
名词解释
- JDK:Java Development Kit
- JRE:Java Runtime Environment
简单地说,JRE就是运行Java字节码的虚拟机。但是,如果只有Java源码,要编译成Java字节码,就需要JDK,因为JDK除了包含JRE,还提供了编译器、调试器等开发工具。
- JSR规范:Java Specification Request
- JCP组织:Java Community Process
为了保证Java语言的规范性,SUN公司搞了一个JSR规范,凡是想给Java平台加一个功能,比如说访问数据库的功能,大家要先创建一个JSR规范,定义好接口,这样,各个数据库厂商都按照规范写出Java驱动程序,开发者就不用担心自己写的数据库代码在MySQL上能跑,却不能跑在PostgreSQL上。
所以JSR是一系列的规范,从JVM的内存模型到Web程序接口,全部都标准化了。而负责审核JSR的组织就是JCP。
一个JSR规范发布时,为了让大家有个参考,还要同时发布一个“参考实现”,以及一个“兼容性测试套件”:
- RI:Reference Implementation
- TCK:Technology Compatibility Kit
一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。
对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
类:类是一个模板,它描述一类对象的行为和状态。
方法:方法就是行为,一个类可以有很多方法。逻辑运算、数据修改以及所有动作都是在方法中完成的。
实例变量:每个对象都有独特的实例变量,对象的状态由这些实例变量的值决定。
Java的类
类名要求(例如class):
程序中public
是访问修饰符,表示该class
是公开的。
不写public
,也能正确编译,但是这个类将无法从命令行执行。
在class
内部,可以定义若干方法(method):
方法定义了一组执行语句,方法内部的代码将会被依次顺序执行。
这里的方法名是main
,返回值是void
,表示没有任何返回值。
public
除了可以修饰class
外,也可以修饰方法。而关键字static
是另一个修饰符,它表示静态方法,Java入口程序规定的方法必须是静态方法,方法名必须为main
,括号内的参数必须是String数组。
方法名也有命名规则,命名和class
一样,但是首字母小写:
在方法内部,语句才是真正的执行代码。Java的每一行语句必须以分号结束。
Java有3种注释,第一种是单行注释,以双斜线开头,直到这一行的结尾结束:(和C语言一样哦)
// 这是注释...
而多行注释以/*
星号开头,以*/
结束,可以有多行:(也和C语言一样哦)
/*
这是注释
blablabla...
这也是注释
*/
还有一种特殊的多行注释,以/**
开头,以*/
结束,如果有多行,每行通常以星号开头:(这种就没有见过啦)
/**
* 可以用来自动创建文档的注释
*
*
*/
public class Hello {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}
这种特殊的多行注释需要写在类和方法的定义处,可以用于自动创建文档。
在Java中,变量分为两种:基本类型的变量和引用类型的变量。基本类型的变量是“持有”某个数值,引用类型的变量是“指向”某个对象。
基本数据类型是CPU可以直接进行运算的类型。Java定义了以下几种基本数据类型:
计算机内存的基本结构。
计算机内存的最小存储单元是字节(byte),一个字节就是一个8位二进制数,即8个bit。它的二进制表示范围从00000000``11111111
,换算成十进制是0255,换算成十六进制是00
~ff
。
内存单元从0开始编号,称为内存地址。每个内存单元可以看作一间房间,内存地址就是门牌号。
一个字节是1byte,1024字节是1K,1024K是1M,1024M是1G,1024G是1T。一个拥有4T内存的计算机的字节数量就是:
4T = 4 x 1024G
= 4 x 1024 x 1024M
= 4 x 1024 x 1024 x 1024K
= 4 x 1024 x 1024 x 1024 x 1024
= 4398046511104
不同的数据类型占用的字节数不一样。Java基本数据类型占用的字节数:
byte 一个字节
short 两个字节
int 四个字节
long 八个字节
float 四个字节
double 八个字节
char 两个字节
byte
恰好就是一个字节,而long
和double
需要8个字节。
对于整型类型,Java只定义了带符号的整型,因此,最高位的bit表示符号位(0表示正数,1表示负数)。各种整型能表示的最大范围如下:
关于为什么叫浮点数->浮点类型的数就是小数,因为小数用科学计数法表示的时候,小数点是可以“浮动”的,如1234.5可以表示成12.345x102,也可以表示成1.2345x103,所以称为浮点数。
对于float
类型,需要加上f
后缀。
浮点数可表示的范围非常大,float
类型可最大表示3.4x1038,而double
类型可最大表示1.79x10308。
布尔类型boolean
只有true
和false
两个值,布尔类型总是关系运算的计算结果。
Java语言对布尔类型的存储并没有做规定,因为理论上存储布尔类型只需要1 bit,但是通常JVM内部会把boolean
表示为4字节整数。
字符类型char
表示一个字符。Java的char
类型除了可表示标准的ASCII外,还可以表示一个Unicode(一种编码方案)字符.
除了上述基本类型的变量,剩下的都是引用类型。例如,引用类型最常用的就是String
字符串.
引用类型的变量类似于C语言的指针,它内部存储一个“地址”,指向某个对象在内存的位置。
定义变量的时候,如果加上final
修饰符,这个变量就变成了常量:常量在定义时进行初始化后就不可再次赋值,再次赋值会导致编译错误。
根据习惯,常量名通常全部大写。
由于类型的名字太长,写起来比较麻烦。如:
StringBuilder sb = new StringBuilder();
如果想省略变量类型,可以使用var
关键字:
var sb = new StringBuilder();
编译器会根据赋值语句自动推断出变量sb
的类型是StringBuilder
。对编译器来说,语句:
var sb = new StringBuilder();
实际上会自动变成:
StringBuilder sb = new StringBuilder();
因此,使用var
定义变量,仅仅是少写了变量类型而已。
定义变量时,要遵循作用域最小化原则,尽量将变量定义在尽可能小的作用域,并且,不要重复使用变量名。
注意事项:
1)整数的除法对于除数为0时运行时将报错,但编译不会报错
2)溢出
整数由于存在范围限制,如果计算结果超出了范围,就会产生溢出,而溢出不会出错,却会得到一个奇怪的结果。
在计算机中,整数总是以二进制的形式表示。
无符号的右移运算,使用>>>
,它的特点是不管符号位,右移后高位总是补0
,因此,对一个负数进行>>>
右移,它会变成正数,原因是最高位的1
变成了0
:
对byte
和short
类型进行移位时,会首先转换为int
再进行位移。
左移实际上就是不断地×2,右移实际上就是不断地÷2。
其中与和非运算与以前学的没什么不同,非运算的规则是,0
和1
互换,符号’~’.
异或运算的规则是,如果两个数不同,结果为1
,否则为0
:
对两个整数进行位运算,实际上就是按位对齐,然后依次对每一位进行运算。
在Java的计算表达式中,运算优先级从高到低依次是:
()
!
~
++
--
*
/
%
+
-
<<
>>
>>>
&
|
+=
-=
*=
/=
在运算过程中,如果参与运算的两个数类型不一致,那么计算结果为较大类型的整型。例如,short
和int
计算,结果总是int
,原因是short
首先自动被转型为int
.
也可以将结果强制转型,即将大范围的整数转型为小范围的整数,当然这个结果很可能是错的(在超出范围时)。
应该选择合适范围的整型(int
或long
),没有必要为了节省内存而使用byte
和short
进行整数运算。
由于浮点数存在运算误差,所以比较两个浮点数是否相等常常会出现错误的结果。正确的比较方法是判断两个浮点数之差的绝对值是否小于一个很小的数:
double r = Math.abs(x - y);
// 判断绝对值是否足够小:
if (r < 0.00001) {
// 可以认为相等
浮点数在内存的表示方法和整数比更加复杂。Java的浮点数完全遵循IEEE-754标准,这也是绝大多数计算机平台都支持的浮点数标准表示方法。
如果参与运算的两个数其中一个是整型,那么整型可以自动提升到浮点型。
整数运算在除数为0
时会报错,而浮点数运算在除数为0
时,不会报错,但会返回几个特殊值:
NaN
表示Not a NumberInfinity
表示无穷大-Infinity
表示负无穷大例如:
double d1 = 0.0 / 0; // NaN
double d2 = 1.0 / 0; // Infinity
double d3 = -1.0 / 0; // -Infinity
这三种特殊值在实际运算中很少碰到,我们只需要了解即可。
可以将浮点数强制转型为整数。在转型时,浮点数的小数部分会被丢掉。如果转型后超过了整型能表示的最大范围,将返回整型的最大值。
如果要进行四舍五入,可以对浮点数加上0.5再强制转型:
`double` d = 2.6;`
`int n = (int) (d + 0.5);`
System.out.println(n);`
对于布尔类型boolean
,永远只有true
和false
两个值。
布尔运算是一种关系运算,包括以下几类(按照优先级排序):
关系运算符:
!
>
,>=
,<
,<=
==
,!=
&&
||
布尔运算的一个重要特点是短路运算。如果一个布尔运算的表达式能提前确定结果,则后续的计算不再执行,直接返回结果。与运算和或运算是短路运算;
因为false && x
的结果总是false
,无论x
是true
还是false
,因此,与运算在确定第一个值为false
后,不再继续计算,而是直接返回false
。
三元运算符b ? x : y
,它根据第一个布尔表达式的结果,分别返回后续两个表达式之一的计算结果。
三元运算b ? x : y
后面的类型必须相同,三元运算也是“短路运算”,只计算x
或y
。
在Java中,字符和字符串是两个不同的类型。
字符类型char
是基本数据类型,它是character
的缩写。一个char
保存一个Unicode字符:
因为Java在内存中总是使用Unicode表示字符,所以,一个英文字符和一个中文字符都用一个char
类型表示,它们都占用两个字节。
还可以直接用转义字符\u
+Unicode编码来表示一个字符:
// 注意是十六进制:
char c3 = '\u0041'; // 'A',因为十六进制0041 = 十进制65,即字符A
char c4 = '\u4e2d'; // '中',因为十六进制4e2d = 十进制20013,即字符中
和char
类型不同,字符串类型String
是引用类型,我们用双引号"..."
表示字符串。一个字符串可以存储0个到任意个字符。
因为字符串使用双引号"..."
表示开始和结束,如果字符串本身恰好包含一个"
字符怎么表示?例如,"abc"xyz"
,编译器就无法判断中间的引号究竟是字符串的一部分还是表示字符串结束。这个时候,我们需要借助转义字符\
:
String s = "abc\"xyz"; // 包含7个字符: a, b, c, ", x, y, z
因为\
是转义字符,所以,两个\\
表示一个\
字符:
String s = "abc\\xyz"; // 包含7个字符: a, b, c, \, x, y, z
常见的转义字符包括:
\"
表示字符"
\'
表示字符'
\\
表示字符\
\n
表示换行符\r
表示回车符\t
表示Tab\u####
表示一个Unicode编码的字符例如:
String s = "ABC\n\u4e2d\u6587"; // 包含6个字符: A, B, C, 换行符, 中, 文
Java的编译器对字符串做了特殊照顾,可以使用+
连接任意字符串和其他数据类型,这样极大地方便了字符串的处理。
从Java 13开始,字符串可以用"""..."""
表示多行字符串(Text Blocks)。举个栗子:
String s = """
SELECT * FROM
users
WHERE id > 100
ORDER BY name DESC
""";
还需要注意到,多行字符串前面共同的空格会被去掉。
如果多行字符串的排版不规则,那么,去掉的空格就会变成这样:
String s = """
......... SELECT * FROM
......... users
.........WHERE id > 100
......... ORDER BY name DESC
......... """;
总是以最短的行首空格为基准。
Java的字符串除了是一个引用类型外,还有个重要特点,就是字符串不可变。
引用类型的变量可以指向一个空值null
,它表示不存在,即该变量不指向任何对象。
定义一个数组类型的变量,使用数组类型“类型[]”,例如,int[]
。和单个基本类型变量不同,数组变量初始化必须使用new int[5]
表示创建一个可容纳5个int
元素的数组。
Java的数组的几个特点:
0
,浮点型是0.0
,布尔型是false
;要访问数组中的某一个元素,需要使用索引。数组索引从0
开始,例如,5个元素的数组,索引范围是0
~4
。
可以修改数组中的某一个元素,使用赋值语句,例如:ns[1] = 79;
。
可以用数组变量.length
获取数组大小(就是长度)。
数组是引用类型,在使用索引访问数组元素时,如果索引超出范围,运行时将报错;
数组元素可以是值类型(如int)或引用类型(如String),但数组本身是引用类型。
在前面的代码中,使用System.out.println()
来向屏幕输出一些内容。
println
是print line的缩写,表示输出并换行。因此,如果输出后不想换行,可以用print()
;
如果要把数据显示成我们期望的格式,就需要使用格式化输出的功能。格式化输出使用System.out.printf()
,通过使用占位符%?
,printf()
可以把后面的参数格式化成指定格式:
Java的格式化功能提供了多种占位符(顾名思义),可以把各种数据类型“格式化”成指定的字符串:
占位符 | 说明 |
---|---|
%d | 格式化输出整数 |
%x | 格式化输出十六进制整数 |
%f | 格式化输出浮点数 |
%e | 格式化输出科学计数法表示的浮点数 |
%s | 格式化字符串 |
注意,由于%表示占位符,因此,连续**两个%%**表示一个%字符本身。
占位符本身还可以有更详细的格式化参数。下面的例子把一个整数格式化成十六进制,并用0补足8位(这个代码看不懂):
public class Main {
public static void main(String[] args) {
int n = 12345000;
System.out.printf("n=%d, hex=%08x", n, n); // 注意,两个%占位符必须传入两个数
}
}
先看一个从控制台读取一个字符串和一个整数的例子:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); // 创建Scanner对象
System.out.print("Input your name: "); // 打印提示
String name = scanner.nextLine(); // 读取一行输入并获取字符串
System.out.print("Input your age: "); // 打印提示
int age = scanner.nextInt(); // 读取一行输入并获取整数
System.out.printf("Hi, %s, you are %d\n", name, age); // 格式化输出
}
}
首先,我们通过import
语句导入java.util.Scanner
,import
是导入某个类的语句,必须放到Java源代码的开头,后面我们在Java的package
中会详细讲解如何使用import
。
然后,创建Scanner
对象并传入System.in
。System.out
代表标准输出流,而System.in
代表标准输入流。直接使用System.in
读取用户输入虽然是可以的,但需要更复杂的代码,而通过Scanner
就可以简化后续的代码。
有了Scanner
对象后,要读取用户输入的字符串,使用scanner.nextLine()
,要读取用户输入的整数,使用scanner.nextInt()
。Scanner
会自动转换数据类型,因此不必手动转换。
Java提供的输出包括:System.out.println()
/ print()
/ printf()
,其中printf()
可以格式化输出;
Java提供Scanner对象来方便输入,读取对应的类型可以使用:scanner.nextLine()
/ nextInt()
/ nextDouble()
/ …
当if
语句块只有一行语句时,可以省略花括号{};但是,省略花括号并不总是一个好主意。假设某个时候,突然想给if
语句块增加一条语句时:由于使用缩进格式,很容易把两行语句都看成if
语句的执行块,但实际上只有第一行语句是if
的执行块。
在使用git这些版本控制系统自动合并时更容易出问题,所以不推荐忽略花括号的写法。
在Java中,判断值类型的变量是否相等,可以使用==
运算符。但是,判断引用类型的变量是否相等即判断二者是否指向同一个对象。两个String类型,它们的内容是相同的,但是,分别指向不同的对象,用==
判断,结果是false。
要判断引用类型的变量内容是否相等,必须使用equals()
方法:
执行语句s1.equals(s2)
时,如果变量s1
为null
,会报NullPointerException
;
使用switch
时,注意case
语句并没有花括号{}
,而且,case
语句具有“穿透性”,漏写break
将导致意想不到的结果:
switch
语句还可以使用枚举类型。
使用switch
时,如果遗漏了break
,就会造成严重的逻辑错误,而且不易在源代码中发现错误。从Java 12开始,switch
语句升级为更简洁的表达式语法,使用类似模式匹配(Pattern Matching)的方法,保证只有一种路径会被执行,并且不需要break
语句;
注意新语法使用->
,如果有多条语句,需要用{}
括起来。不要写break
语句,因为新语法只会执行匹配的语句,没有穿透效应。
使用新的switch
语法还可以直接返回值,栗子:
public class Main {
public static void main(String[] args) {
String fruit = "apple";
int opt = switch (fruit) {
case "apple" -> 1;
case "pear", "mango" -> 2;
default -> 0;
}; // 注意赋值语句要以;结束
System.out.println("opt = " + opt);
}
}
大多数时候,在switch
表达式内部,我们会返回简单的值。
但是,如果需要复杂的语句,我们也可以写很多语句,放到{...}
里,然后,用yield
返回一个值作为switch
语句的返回值:
public class Main {
public static void main(String[] args) {
String fruit = "orange";
int opt = switch (fruit) {
case "apple" -> 1;
case "pear", "mango" -> 2;
default -> {
int code = fruit.hashCode();//这里看不懂,应该就是所说的复杂的语句
yield code; // switch语句返回值
}
};
System.out.println("opt = " + opt);
}
}
//注意千万不要漏写break
,建议打开fall-through
警告;
//总是写上default
,建议打开missing default
警告;
for
循环的功能非常强大,它使用计数器实现循环。for
循环会先初始化计数器,然后,在每次循环前检测循环条件,在每次循环后更新计数器。计数器变量通常命名为i
。
注意for
循环的初始化计数器总是会被执行,并且for
循环也可能循环0次。
使用for
循环时,千万不要在循环体内修改计数器的值,在循环体中修改计数器常常导致莫名其妙的逻辑错误。
它可以更简单地遍历数组:
public class Main {
public static void main(String[] args) {
int[] ns = { 1, 4, 9, 16, 25 };
for (int n : ns) {
System.out.println(n);
}
}
}
和for
循环相比,for each
循环的变量n不再是计数器,而是直接对应到数组的每个元素。for each
循环的写法也更简洁。但是,for each
循环无法指定遍历顺序,也无法获取数组的索引。
除了数组外,for each
循环能够遍历所有“可迭代”的数据类型,包括后面会介绍的List
、Map
等。
break
语句可以跳出当前循环;
break
语句通常配合if
,在满足条件时提前结束整个循环;
break
语句总是跳出最近的一层循环;
continue
语句可以提前结束本次循环;
continue
语句通常配合if
,在满足条件时提前结束本次循环.
笔记暂告一段落~
初次编写于2020/12/5日;
一改于2021/1/22日。