前言
本文是我暑假短时自学的总结,综合了菜鸟教程Java 教程 | 菜鸟教程 (runoob.com)、mooc上翁恺老师的零基础学Java零基础学Java语言_浙江大学_中国大学MOOC(慕课) (icourse163.org)以及bilibili狂神说的Java零基础学习视频通俗易懂遇见狂神说的个人空间_哔哩哔哩_Bilibili,因为是短时的自学,如有不全或者错误的地方,欢迎补充和更正。
环境配置和编程工具
1 Java基本语法
1.1 命名规则
具体可以参考阿里巴巴Java开发手册;
我们要从一开始就养成一个好的命名习惯,尽量做到见名知意,而不是利用拼音或者只有自己能懂的一些五花八门的名称,命名也要做到尽量标准!
1.1.1 Java命名的敏感性
Java是一门对大小写高度敏感的一门编程语言;
例如:
1.1.2 类名
类名应该将名字的所以字母的首字母大写,例如:MyFirstJavaClass。
1.1.3 方法名
方法名采用首字母小写,若名字由多个字母组成则从第二个字母开始后面的所有字母都要第一个字母大写开头。
这种命名方法叫做驼峰命名法骆驼命名法_百度百科 (baidu.com)。
1.1.4 源文件名
源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记 Java 是大小写敏感的),文件名的后缀为 .java。(如果文件名和类名不相同则会导致编译错误)
1.1.5 主方法入口
所有的 Java 程序由 public static void main(String[] args) 方法开始执行。
在eclipse中,eclipse为我们提供了很方便的创建主方法的选项,
例如:
但是我认为在学习初期应该学着自己打出这段代码,一是可以熟悉Java中方法的命名方法,为后面学习函数打好基础。
1.2 标识符
Java 中标识符是为方法、变量或其他用户定义项所定义的名称。标识符可以有一个或多个字符。在 Java 语言中,标识符的构成规则如下:
- 标识符由数字(09)和字母(AZ 和 a~z)、美元符号($)、下划线(_)以及 Unicode 字符集中符号大于 0xC0 的所有符号组合构成(各符号之间没有空格)。
- 标识符的第一个符号为字母、下划线和美元符号,后面可以是任何字母、数字、美元符号或下划线。
1.3 修饰符
Java的修饰符分为两类 访问修饰符和非访问修饰符。
具体详细用法Java中各类修饰符的使用总结(看完这篇就够了)_夏日清风-CSDN博客_java 修饰符。
1.4 变量
Java主要有一下几种变量:
-
局部变量
package md01; public class Md01 { public static void main(String[] args) { int x=10;//创建一个隶属于主函数的局部变量X } public static int func(int i) { x=1;//X在func这个函数中未定义 System.out.println(x);//代码编译运行时无法得到10这个结果 return 0; } }
-
类变量(静态变量)
类变量也就是静态变量(被static修饰的变量),类变量的定义以及使用方法如下
-
static 修饰的成员变量和方法,从属于类。
-
普通变量和方法从属于对象。
-
静态方法不能调用非静态成员,编译会报错。
-
用static修饰后的变量,也就是静态变量,它是一个全局变量
-
静态变量的数据储存在共享代码区,也就是同一组数据,可以由不同的类来进行管理和修改,如下,创建一个静态变量x,
package md01; public class Md01 { static int x=10; public Md01() {} public static void main(String[] args) { Md01 s1=new Md01(); Md01 s2=new Md01(); s1.x=20; System.out.println(s1.x); System.out.println(s2.x); } }
修改s1中x的值,s2中代码的值按常识来说应该是不变的,但正是由于静态变量的共同管理的性质,改变s1中x的值的同时,s2中的x的值也随之改变。
-
-
成员变量(非静态变量)
在 Java 中对象的属性也称为成员变量。
成员变量、类变量、局部变量的区别
以下博客整理的非常简单明了,所以这里就不做多的解释了
成员变量、类变量、局部变量的区别_du_minchao的专栏-CSDN博客_成员变量
1.5 数组
数组是储存在堆上的对象,可以保存多个同类型变量。(这里只是概念的介绍,后面会详细的解释数组)
1.6 关键字
类别 | 关键字 | 说明 |
---|---|---|
访问控制 | private | 私有的 |
protected | 受保护的 | |
public | 公共的 | |
default | 默认 | |
类、方法和变量修饰符 | abstract | 声明抽象 |
class | 类 | |
extends | 扩充,继承 | |
final | 最终值,不可改变的 | |
implements | 实现(接口) | |
interface | 接口 | |
native | 本地,原生方法(非 Java 实现) | |
new | 新,创建 | |
static | 静态 | |
strictfp | 严格,精准 | |
synchronized | 线程,同步 | |
transient | 短暂 | |
volatile | 易失 | |
程序控制 语句 | break | 跳出循环 |
case | 定义一个值以供 switch 选择 | |
continue | 继续 | |
default | 默认 | |
do | 运行 | |
else | 否则 | |
for | 循环 | |
if | 如果 | |
instanceof | 实例 | |
return | 返回 | |
switch | 根据值选择执行 | |
while | 循环s | |
错误处理 | assert | 断言表达式是否为真 |
catch | 捕捉异常 | |
finally | 有没有异常都执行 | |
throw | 抛出一个异常对象 | |
throws | 声明一个异常可能被抛出 | |
try | 捕获异常s | |
包相关 | import | 引入 |
package | 包 | |
基本类型 | boolean | 布尔型 |
byte | 字节型 | |
char | 字符型 | |
double | 双精度浮点 | |
float | 单精度浮点 | |
int | 整型 | |
long | 长整型 | |
short | 短整型 | |
变量引用 | super | 父类,超类 |
this | 本类 | |
void | 无返回值 | |
保留关键字 | goto | 是关键字,但不能使用 |
const | 是关键字,但不能使用 | |
null | 空 |
标识符不能和关键字重复,这一点要在命名的时候特别注意!!!!
这些关键字,记?记是不可能记的!这辈子都不可能记的! (QwQ)哈哈,开个玩笑。
这些关键词在学习编程的过程中会用到,不用死记硬背,等编程的时间够长了,关键字也自然知道了(我也还是个小白QAQ)。
1.7 枚举
这里只做举例
import java.util.Scanner;
public class Md05 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
//枚举:找零钱为例(翁恺老师视频中例子)
//这个是在人民币能整除的基础下运行的,为的是引出枚举的概念
Scanner in = new Scanner(System.in);
//从键盘接收数据
int amount=0;
//定义一个需要找零的数
if(in.hasNextInt())
{
amount = in.nextInt();
//输入需要找零的金额
}
out:
for(int one=0;one<=amount;one++)
//第一层循环表示的是一元的张数,我们知道要可以用amount张一元来达到找零的目的
//所以第一层循环amount次
{
for(int five=0;five<=amount/5;five++)
//同理,第二层循环表示的是五元的张数,但是我们只需要amount/5就够找零了
//所以第二层循环amount/5次
{
for(int ten=0;ten<=amount/10;ten++)
//同理,第三层循环表示的是十元的张数,但是我们只需要amount/10就够找零了
//所以第三层循环amount/10次
{
for(int twenty=0;twenty<=amount/20;twenty++)
//同理,第四层循环表示的是20元的张数,但是我们只需要amount/20就够找零了
//所以第四层循环amount/20次
{
if((one+five*5+ten*10+twenty*20)==amount)
//最后将这些数字相加,如果和输入金额相等,则表明符合找零条件
{
//输出符合条件的找零方法
System.out.println(one+"张一元\t"+five+"张五元\t"+ten+"张10元\t"+twenty+"张20元\t");
break out;//这里涉及到循环控制,我们给第一层循环取个名字叫做out,
//这样直接break out;就能跳出第一层循环
//这里break是因为只想得到一种找零方式,如果你想看到所有的找零方式,也可以不break;
//直接让循环完成就行。
}
}
}
}
}
in.close();
}
}
零基础学Java语言_浙江大学_中国大学MOOC(慕课) (icourse163.org)中有很多有意思的例子,大家感兴趣可以去自行学习。
2 Java特殊的交互方式(Scanner类)
2.1交互最基本的格式和注意事项
import java.util.Scanner;//引入Scanner方法
public class md02 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);//接收数据(这里的Scanner前面的in可以取符合命名规则的名字)
in.close();//关闭输入流,释放内存(一定要用完再关闭)
}
}
注意:使用Scanner方法进行人机交互之前,一定要引入Scanner这个方法,并且使用完毕后,要记得关闭输入流释放内存
这里介绍过的用法在后面的各种交互方法中不再指明!!!(好吧,其实是因为懒>_<)
2.2 各种交互方法
import java.util.Scanner;
public class md02 {
public static void main(String[] args) {
//next用法:
Scanner in = new Scanner(System.in);//从键盘接收数据
System.out.println("next方式接收:");
if(in.hasNext())//判断是否还有输入
{
String str1=in.next();//将读取到的数据附值给str1;
System.out.println("输入的str1为:"+str1);//这里的+起到的是链接字符串的作用(后面会有+号各种情况下的作用)
}
in.close();
}
}
运行结果如下:
next方式接收:
一只小白 12
输入的str1为:一只小白
import java.util.Scanner;
public class md02 {
public static void main(String[] args) {
//nextLine用法:
Scanner in = new Scanner(System.in);//从键盘接收数据
System.out.println("nextLine方式接收:");
if(in.hasNextLine())//判断是否还有输入
{
String str1=in.nextLine();//将读取到的数据附值给str1;
System.out.println("输入的str1为:"+str1);//这里的+起到的是链接字符串的作用(后面会有+号各种情况下的作用)
}
in.close();
}
运行结果如下:
nextLine方式接收:
一只小白 12
输入的str1为:一只小白 12
经过对比我们不难发现next()和nextLine()方法输入的东西是相同的,但是输出的结果却不同,造成结果不用的原因是next()和nextLine()判断输入结束的方式不同,并且next()和nextLine()在读取输入的数据时也有着具大的差异。
2.3 nextLine()和next()的区别
next:
- 1、一定要读取到有效字符后才可以结束输入。
- 2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
- 3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
- next() 不能得到带有空格的字符串。
nextLine:
- 1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
- 2、可以获得空白
参考自菜鸟教程的next() 与 nextLine() 区别Java Scanner 类 | 菜鸟教程 (runoob.com)
其他的一些方法(以整形和单精度浮点型为例)
import java.util.Scanner;
public class Md03 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//从键盘接收数据
System.out.println("输入整数数据:");
//输出提示信息
if(in.hasNextInt())
//判断输入是否为整数
{
int x=in.nextInt();
//接收整数
System.out.println("输入的整数为:"+x);
}else
{
System.out.println("请输入整数!");
//若输入的不为整数,输出错误信息
}
System.out.println("输入小数数据:");
//输出提示信息
if(in.hasNextFloat())
//判断输入是否为整数
{
float x=in.nextInt();
//接收浮点数(也就是小数)
System.out.println("输入的小数为:"+x);
}else
{
System.out.println("请输入整数!");
//若输入不为整数,输出错误信息
}
in.close();
//别忘了关闭输入!!!!!!!!!!!!!!!! 别忘了关闭输入!!!!!!!!!!!!!!!! 别忘了关闭输入!!!!!!!!!!!!!!!!(重要的事情说三遍)
}
}
这里只列举了一部分,实际上的输入根据自己的想要输入的类型来更改使用的方法,最后!别忘了关闭输入!(@w@)
2.4 输入多个数据
以计算总和和平均数为例子:
import java.util.Scanner;
public class Md06 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//从键盘接收数据
float sum=0f;
//此处的sum表示输入的数的总和
//Java中虽然float和double都表示浮点数,但是我们定义float单精度
//浮点数时,一定要注意加上一个f来个double双精度浮点数来区分(否则会报错)
float aver=0f;
//aver average表示平均数,这里用aver简略表示
int n=0;
//表示要输入的数的个数
Boolean count=false;
//判断是否有大于平均数的数
int cnt=0;
//记录下大于平均数的数的个数
n=in.nextInt();
//接收数据
float [] number = new float[n];
//定义一个数组来存储输入的数字
for(int i=0;i<n;i++)
{
number[i]=in.nextFloat();
//接收数据
sum+=number[i];
//sum+=number[i]相当于sum=sum+number[i],计算总数
}
aver=sum/(float)n;
//计算平均数
float [] b = new float[n];
//定义一个数组大小为n(因为最多有n个数据)来存放大于平均数的数字
System.out.println("这"+n+"个数的和为:"+sum+"平均数为:"+aver);
//输出n个数的和以及平均数
for(float x : number)
//利用for each循环来寻找大于平均数的数
{
if(x>aver)
{
count=true;
//如果有大于平均数的数,则让count为true,表示有大于平均数的数
b[cnt]=x;
//将大于平均数的数存入数组
cnt++;
//存入后需要让下标自增,方便存储下一个数
}
}
if(count)
//判断是否有大于平均数的数
//有则输出这些数
{
System.out.print("大于"+aver+"的数有: ");
for(int i=0;i<cnt;i++)
{
System.out.print(b[i]+" ");
}
}else{
//没有则输出没有的提示信息
System.out.print("没有比"+aver+"大的数");
}
in.close();
//关闭输入
}
}
利用循环可以读入多个数据
3 对象和类
由于我是速学,所以对于对象和类我总结的不深入,这里给链接
4 基本数据类型
4.1内置数据类型
Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。
byte:
- byte 数据类型是8位、有符号的,以二进制补码表示的整数;
- 最小值是 -128(-2^7);
- 最大值是 127(2^7-1);
- 默认值是 0;
- byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一;
- 例子:byte a = 100,byte b = -50。
short:
- short 数据类型是 16 位、有符号的以二进制补码表示的整数
- 最小值是 -32768(-2^15);
- 最大值是 32767(2^15 - 1);
- Short 数据类型也可以像 byte 那样节省空间。一个short变量是int型变量所占空间的二分之一;
- 默认值是 0;
- 例子:short s = 1000,short r = -20000。
int:
- int 数据类型是32位、有符号的以二进制补码表示的整数;
- 最小值是 -2,147,483,648(-2^31);
- 最大值是 2,147,483,647(2^31 - 1);
- 一般地整型变量默认为 int 类型;
- 默认值是 0 ;
- 例子:int a = 100000, int b = -200000。
long:
- long 数据类型是 64 位、有符号的以二进制补码表示的整数;
- 最小值是 -9,223,372,036,854,775,808(-2^63);
- 最大值是 9,223,372,036,854,775,807(2^63 -1);
- 这种类型主要使用在需要比较大整数的系统上;
- 默认值是 0L;
- 例子: long a = 100000L,Long b = -200000L。
"L"理论上不分大小写,但是若写成"l"容易与数字"1"混淆,不容易分辩。所以最好大写。
float:
- float 数据类型是单精度、32位、符合IEEE 754标准的浮点数;
- float 在储存大型浮点数组的时候可节省内存空间;
- 默认值是 0.0f;
- 浮点数不能用来表示精确的值,如货币;
- 例子:float f1 = 234.5f。
double:
-
double 数据类型是双精度、64 位、符合 IEEE 754 标准的浮点数;
-
浮点数的默认类型为 double 类型;
-
double类型同样不能表示精确的值,如货币;
-
默认值是 0.0d;
-
例子:
double d1 = 7D ; double d2 = 7.; double d3 = 8.0; double d4 = 8.D; double d5 = 12.9867;
7 是一个 int 字面量,而 7D,7. 和 8.0 是 double 字面量。
boolean:
- boolean数据类型表示一位的信息;
- 只有两个取值:true 和 false;
- 这种类型只作为一种标志来记录 true/false 情况;
- 默认值是 false;
- 例子:boolean one = true。
char:
-
char 类型是一个单一的 16 位 Unicode 字符;
-
最小值是 \u0000(十进制等效值为 0);
-
最大值是 \uffff(即为 65535);
-
char 数据类型可以储存任何字符;
-
例子:char letter = ‘A’;。
参考自菜鸟教程
4.2 Java常量
用final定义的一个数,叫做一个常量(常量通常用全大写来命名,如:PI),常量定义了之后是不可改变的。
public class Md07 {
public static void main(String[] args) {
final double PI=3.1415926;
PI=1;
System.out.println(PI);
}
}
Exception in thread "main" java.lang.Error: 无法解析的编译问题:
不能对final局部变量 PI 赋值。它必须为空白,并且不使用复合赋值
at md01/md01.Md07.main(Md07.java:7)
4.3 转义字符
符号 | 字符含义 |
---|---|
\n | 换行 (0x0a) |
\r | 回车 (0x0d) |
\f | 换页符(0x0c) |
\b | 退格 (0x08) |
\0 | 空字符 (0x0) |
\s | 空格 (0x20) |
\t | 制表符 |
" | 双引号 |
’ | 单引号 |
\ | 反斜杠 |
\ddd | 八进制字符 (ddd) |
\uxxxx | 16进制Unicode字符 (xxxx) |
4.4 自动类型转换
整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。
转换从低级到高级。
低 ------------------------------------> 高
byte,short,char—> int —> long—> float —> double
4.5 强制类型转换
public class Md07 {
public static void main(String[] args) {
double x=1.5555;
int a=(int)x;//强制将double双精度浮点型的x转换为int整形
System.out.println(a);//输出结果为1(所以强制转换为整型时是舍弃小数点后面的位数,而不是四舍五入)
}
}
在要进行变量前用(要转换成的类型)来进行强制转换
4.6 隐形强制类型转换
就比如前面的
float a=0.1f;
后面跟上的f(F也可以)进行的就是隐形强制类型转换
5 变量类型
Java的变量类型分为局部变量、类变量(静态变量)、实例变量
具体可见Java基本语法中的变量章节
6 修饰符
由于修饰符的介绍过于复杂,且修饰符过于多
具体参考Java 修饰符 | 菜鸟教程 (runoob.com)
7 运算符
计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量。我们可以把运算符分成以下几组:
- 算术运算符
- 关系运算符
- 位运算符
- 逻辑运算符
- 赋值运算符
- 其他运算符
7.1 算术运算符
操作符 | 描述 | 例子 |
---|---|---|
+ | 加法 - 相加运算符两侧的值 | A + B 等于 30 |
- | 减法 - 左操作数减去右操作数 | A – B 等于 -10 |
* | 乘法 - 相乘操作符两侧的值 | A * B等于200 |
/ | 除法 - 左操作数除以右操作数 | B / A等于2 |
% | 取余 - 左操作数除以右操作数的余数 | B%A等于0 |
++ | 自增: 操作数的值增加1 | B++ 或 ++B 等于 21 |
– | 自减: 操作数的值减少1 | B-- 或 --B 等于 19 |
//各个运算符的运算:(注意自增和自减++在变量前面和后面的区别)
public class Md08 {
public static void main(String[] args) {
int a=11;
int b=12;
int c=13;
int d=14;
System.out.println("a + b = "+(a+b));
//输出a + b = 23
System.out.println("a - b = "+(a-b));
//输出a - b = -1
System.out.println("a * b = "+(a*b));
//输出a * b = 132
System.out.println("a / b = "+(a/b));
//输出a / b = 0
System.out.println("a % b = "+(a%b));
//输出a % b = 11
System.out.println("c++ = "+(c++));
//输出c++ = 13
System.out.println("++c = "+(++c));
//输出++c = 15
System.out.println("d-- = "+(d--));
//输出d-- = 14
System.out.println("--d = "+(--d));
//输出--d = 12
}
}
7.1.1 自增和自减
前缀自增自减法(++a,–a): 先进行自增或者自减运算,再进行表达式运算。
后缀自增自减法(a++,a–): 先进行表达式运算,再进行自增或者自减运算。
这也是如上实例中++和–运算符放在变量前或者变量后运算结果不同的根本原因。
7.1.2 “+”运算符的一些特殊运算方法
public class Md07 {
public static void main(String[] args) {
int i=1;
int j=10;
String a="abc";
System.out.println(i);
System.out.println(j);
System.out.println(a);
System.out.println(i+j);
//起加法功能,将两个整数i,j相加并输入结果
System.out.println(a+i);
//起拼接功能,如果“+”前面或者后面有加号则起拼接作用
//注意:这个操作会自动将int型的i转换为字符串后拼接
System.out.println(a+i+j);
//起拼接功能,如果“+”前面或者后面有加号则起拼接作用
//注意:这个操作会自动将int型的i和j转换为字符串后拼接
System.out.println(a+(i+j));
//"+"先是服从优先级,将括号里的两个整型相加后,再转
//换成字符串后与字符串a拼接
}
}
7.2 关系运算符
public class Md09 {
public static void main(String[] args) {
int a=11;
int b=22;
System.out.println("a==b:"+(a==b));
System.out.println("a!=b:"+(a!=b));
System.out.println("a>b:"+(a>b));
System.out.println("a<b:"+(a<b));
System.out.println("a>=b:"+(a>=b));
System.out.println("a<=b:"+(a<=b));
}
}
输出结果:
a==b:false
a!=b:true
a>b:false
a<b:true
a>=b:false
a<=b:true
运算符 | 描述 | 例子 |
---|---|---|
== | 检查如果两个操作数的值是否相等,如果相等则条件为真。 | (A == B)为假。 |
!= | 检查如果两个操作数的值是否相等,如果值不相等则条件为真。 | (A != B) 为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是那么条件为真。 | (A> B)为假。 |
< | 检查左操作数的值是否小于右操作数的值,如果是那么条件为真。 | (A <B)为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是那么条件为真。 | (A> = B)为假。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是那么条件为真。 | (A <= B)为真。 |
值得一提的是,关系运算返回的值为Boolean的值,值只有true和false两种返回值
7.3 位运算符
下表列出了位运算符的基本运算,假设整数变量 A 的值为 60 和变量 B 的值为 13:
操作符 | 描述 | 例子 |
---|---|---|
& | 如果相对应位都是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即 1111 |
>>> | 按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。 |
7.4 逻辑运算符
public class Md10 {
public static void main(String[] args) {
boolean a=true;
boolean b=false;
System.out.println("a && b = " + (a&&b));
System.out.println("a || b = " + (a||b) );
System.out.println("!(a && b) = " + !(a && b));
}
}
//输出结果
a && b = false
a || b = true
!(a && b) = true
下表列出了逻辑运算符的基本运算,假设布尔变量A为真,变量B为假
操作符 | 描述 | 例子 |
---|---|---|
&& | 称为逻辑与运算符。当且仅当两个操作数都为真,条件才为真。 | (A && B)为假。 |
| | | 称为逻辑或操作符。如果任何两个操作数任何一个为真,条件为真。 | (A | | B)为真。 |
! | 称为逻辑非运算符。用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。 | !(A && B)为真。 |
8 循环结构
- for 循环
- while 循环
- do…while 循环
8.1 for循环
for循环的基本结构是
for(初始化; 布尔表达式; 更新) {
//代码语句
}
public class Md10 {
public static void main(String[] args) {
for(int i=0;i<10;i++)
{
System.out.println(i);
}
}
}
输出结果为:
0
1
2
3
4
5
6
7
8
9
for循环中的条件可以不在for循环结构体中定义或者使用,但是for循环中各个语句之间的;号不能省略
8.1.1for Each循环(增强for循环)
for(声明语句 : 表达式)
{
//代码句子
}
public class Md10 {
public static void main(String[] args) {
int[] number = {1,2,3,4,5,6,7};
for(int x: number)
{
System.out.print(x+",");
}
}
}
//输出结果
1,2,3,4,5,6,7,
for each循环会遍历数组中的所有元素,将这些元素依次附值给定义的x。
public class Md10 {
public static void main(String[] args) {
int[] number = {1,2,3,4,5,6,7};//定义一个数组
for(int x: number)
{
x=1;//尝试用for each循环改变原数组
System.out.print(x+",");
}
System.out.println();
System.out.println("利用for each循环改变后的原数组:");
for(int i=0;i<number.length;i++)
{
System.out.print(number[i]+",");//遍历后发现改变失败
}
int[] number1= {1,2,3,4,5,6};//定义一个新数组
System.out.println();
System.out.println("利用for循环改变后的原数组:");
for(int i=0;i<number1.length;i++)
{
number1[i]=1;//尝试用for循环改变原数组
}
for(int i=0;i<number1.length;i++)//这里的number1.length表示的是数组
{
System.out.print(number1[i]+",");//遍历后发现改变成功
}
}
}
输出结果为:
1,1,1,1,1,1,1,
利用for each循环改变后的原数组:
1,2,3,4,5,6,7,
利用for循环改变后的原数组:
1,1,1,1,1,1,
注意:利用for each遍历是无法改变原数组中的数据的,但是利用for循环可以更改
8.2 while循环
while循环的基本结构(while循环时最基本的循环结构)
while( 布尔表达式 ) {
//循环内容
}
while后面括号内的布尔表达式若为true则继续循环。
public class Md11 {
public static void main(String[] args) {
int a=0;
while(a!=10)
{
System.out.print(a+" ");
a++;
}
}
}
输出内容:
0 1 2 3 4 5 6 7 8 9
while循环只要括号内的布尔表达式不为false就会一直循环下去,由于while循环是先判断后循环,所以while循环最少循环次数为0
8.3 do…while循环
public class Md12 {
public static void main(String[] args) {
int a=0;
do {
System.out.print(a+" ");
a++;
}while(a!=10);
}
}
输出结果:
0 1 2 3 4 5 6 7 8 9
与while循环不同的是,do…while是先循环后判断,所以循环最少会循环一次
8.4 循环控制语句
8.4.1 break语句
break;会跳出当前这一层循环
public class Md13 {
public static void main(String[] args) {
for(int i=1;i<10;i++)
{
if(i==5)
{
System.out.print("break");
break;
}
System.out.print(i+" ");
}
}
}
输出结果:
1 2 3 4 break
但是如果我们有两层循环呢?
public class Md14 {
public static void main(String[] args) {
for(int i=0;i<10;i++)
{
for(int j=0;i<10;j++)
{
if(j==5)
{
System.out.println("break");
break;
}
}
System.out.println(i);
}
}
}
输出结果:
break
0
break
1
break
2
break
3
break
4
break
5
break
6
break
7
break
8
break
9
就像我开头说的break语句只能跳出当前一层的循环。
8.4.2 Java提供的跳出多层循环的方法
前面说了break只能跳出一层循环,所当我们想要跳出多层循环时,难道还要写很多break去一层一层的跳出吗?
答案是:不用
public class Md14 {
public static void main(String[] args) {
out://为最外层循环起一个名字叫做out
for(int i=0;i<10;i++)
{
for(int j=0;i<10;j++)
{
if(j==5)
{
System.out.println("break");
System.out.println(j);
break out;//这里直接break out;代表的是跳出out这个循环,也就是结束最外层的循环
}
}
System.out.println(i);
}
}
}
输出结果如下:
break
5
我们可以看到,利用这个方法确实跳出了外层循环,且我们只用了一个break;而不是预想的那样一层一层的break出来。
8.4.3 continue语句
continue 适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代。
在 for 循环中,continue 语句使程序立即跳转到更新语句。
在 while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句。
public class Md15 {
public static void main(String[] args) {
for(int i=0;i<5;i++)
{
if(i==2)
{
continue;//continue跳出当前的循环,继续下一次循环
}
System.out.println(i);
}
}
}
输出结果:
0
1
3
4
我们可以看到并没有输出2,是因为2那一层的循环被跳出了。
8.4.4 continue的特殊用法
和break一样,如果多层循环的话,continue是只能处理一个循环体的,所以也同样可以采用给想要continue的循环命名后直接continue想要的循环,实例如下:
public class Md16 {
public static void main(String[] args) {
out:
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
if(i==2)
{
continue out;
}
}
System.out.println(i);
}
}
}
输出结果:
0
1
3
4
9 条件语句
9.1 if…else语句
以求100以内的素数为例子
public class Md17 {
//我们都知道如果一个数是素数,那么这个数的倍数就一定不是素数
//以下程序就是按照这个思想来的
public static void main(String[] args) {
Boolean[] isPrime= new Boolean[100];//定义一个boolean数组,因为这里求的是100以内的素数,所以这个数组大小为100
for(int i=0;i<isPrime.length;i++)//由于boolean数组的默认值是null,这里我们用true表示是素数(false也行)
{
isPrime[i]=true;//先假定所有数都为素数,后面用判断语句给不是素数的数附值false
}
for(int i=2;i<isPrime.length;i++)//由于1既不是素数也不是合数,所以从2开始循环判断
{
if(isPrime[i])//如果是素数则进入循环,由于2是素数,所以开始内层的循环,依次关掉2的倍数
{
for(int k=2;i*k<isPrime.length;k++)
//这里从2开始循环是因为1*n等于n,在这个循环判断中没有意义,所以从2开始循环
{
isPrime[i*k]=false;//给所有2的倍数附值false表示不是素数
}
}
}
for(int i=2;i<isPrime.length;i++)
{
if(isPrime[i])
{
System.out.print(i+" ");//循环输出100以内的素数
}
}
}
}
if…else语句可以翻译作:如果…否则,就相当于if后面的语句如果为true就执行if后的语句,否则执行else中的语句。
9.2 if…else嵌套语句
public class Md18 {
public static void main(String[] args) {
int x=10;
int y=20;
if(x>=y)
{
if(x>y)
{
System.out.println(x+">"+y);
}else
{
System.out.println(x+"="+y);
}
}else
{
System.out.println(x+"<"+y);
}
}
}
注意:else总是跟离自己最近的一个else匹配的,而不一定是与第一个if匹配
10 switch case选择语句
用题目来说明switch case语句
import java.util.Scanner;
public class Md19 {
public static void main(String[] args) {
/*某百货商场进行打折促销活动,消费金额(p)越高,折扣(d)越大,标准如下。
消费金额(p) 折扣(d)
p<1000 0%
1000≤p<2000 5%
2000≤p<5000 10%
5000≤p<10000 15%
p≥10000 20%
从键盘输入消费金额,编程输出折扣率和实付金额。使用switch语句实现。*/
Scanner in = new Scanner(System.in);
//从键盘输入
double p = in.nextInt();
//接收数据
int a=(int) (p/1000);//简化数据,方便使用switch case语句求解
//由于1000 2000 5000 10000这些关键的判断点都可以被1000整除得到一个整数
//这些整数就能简化程序,使用swich case进行解题(当然if...else也可以解题)
switch(a)
//switch 语句中的变量类型可以是: byte、short、int 或者 char。从 Java SE 7 开始,switch 支持字符串 String 类型 //了,同时 case 标签必须为字符串常量或字面量。
{
case 0:System.out.println("您未满足折扣条件,实付金额为:"+p);break;
//未满1000元,不打折
case 1:System.out.println("您享受95折,实付金额为:"+p*0.95);break;
//由强制类型转换的规则可以知道,1000~2000不包括2000之间得数先除1000再强制转换得到得都是1,符合题目中的9折
case 2:
case 3:
case 4:System.out.println("您享受9折,实付金额为:"+p*0.9);break;
//由于case语句要遇到break;语句才结束,所以这里的2,3,4都输出同一个信息,也就是题中的(2000,3000,4000)
//享受95折
case 5:
case 6:
case 7:
case 8:
case 9:System.out.println("您享受85折,实付金额为:"+p*0.85);break;
//同理,这里的5,6,7,8,9分别对应题中的5000,6000,7000,8000,90000,用户享受85折
default:System.out.println("您享受8折,实付金额为:"+p*0.8);break;
//default的用法和if...else语句中的else用法相当,如果case里面没有的内容,就执行default中的语句
//这里的defalut对应题目中的p>=10000的情况,用户享受8折
}
in.close();
}
}
注意:case语句一定是遇到break语句才结束,由于default是最后执行判断的语句,因此,default语句不需要以break语句结尾
11 特殊的方法Math类
序号 | 方法与描述 |
---|---|
1 | xxxValue() 将 Number 对象转换为xxx数据类型的值并返回。 |
2 | compareTo() 将number对象与参数比较。 |
3 | equals() 判断number对象是否与参数相等。 |
4 | valueOf() 返回一个 Number 对象指定的内置数据类型 |
5 | toString() 以字符串形式返回值。 |
6 | parseInt() 将字符串解析为int类型。 |
7 | abs() 返回参数的绝对值。 |
8 | ceil() 返回大于等于( >= )给定参数的的最小整数,类型为双精度浮点型。 |
9 | floor() 返回小于等于(<=)给定参数的最大整数 。 |
10 | rint() 返回与参数最接近的整数。返回类型为double。 |
11 | round() 它表示四舍五入,算法为 Math.floor(x+0.5),即将原来的数字加上 0.5 后再向下取整,所以,Math.round(11.5) 的结果为12,Math.round(-11.5) 的结果为-11。 |
12 | min() 返回两个参数中的最小值。 |
13 | max() 返回两个参数中的最大值。 |
14 | exp() 返回自然数底数e的参数次方。 |
15 | log() 返回参数的自然数底数的对数值。 |
16 | pow() 返回第一个参数的第二个参数次方。 |
17 | sqrt() 求参数的算术平方根。 |
18 | sin() 求指定double类型参数的正弦值。 |
19 | cos() 求指定double类型参数的余弦值。 |
20 | tan() 求指定double类型参数的正切值。 |
21 | asin() 求指定double类型参数的反正弦值。 |
22 | acos() 求指定double类型参数的反余弦值。 |
23 | atan() 求指定double类型参数的反正切值。 |
24 | atan2() 将笛卡尔坐标转换为极坐标,并返回极坐标的角度值。 |
25 | toDegrees() 将参数转化为角度。 |
26 | toRadians() 将角度转换为弧度。 |
27 | random() 返回一个随机数。 |
注意:所有的Math方法都要以:Math.(方法)的方式来调用,例如:Math.floor();
12 包裹类型
基本类型 | 包裹类型 |
---|---|
boolean | Boolean |
char | Character |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
由包裹类型可以看出,Java是一门严格区分大小写的课程(在编程过程中一定要注意区分大小写)
13 String类
13.1 String 方法
下面是 String 类支持的方法,更多详细,参看 Java String API 文档:
13.2 String StringBuffer StringBuilder的区别
String
String:字符串常量,字符串长度不可变。Java 中 String 是 immutable(不可变)的。
String 类的包含如下定义:
/** The value is used for character storage. */
private final char value[];
/** The offset is the first index of the storage that is used. */
private final int offset;
/** The count is the number of characters in the String. */
private final int count;
用于存放字符的数组被声明为 final 的,因此只能赋值一次,不可再更改。
StringBuffer(JDK1.0)
StringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用 StringBuffer,如果想转成 String 类型,可以调用 StringBuffer 的 toString() 方法。
Java.lang.StringBuffer 线程安全的可变字符序列。在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。
- append 方法始终将这些字符添加到缓冲区的末端;
- insert 方法则在指定的点添加字符。
例如,如果 z 引用一个当前内容是 start 的字符串缓冲区对象,则此方法调用 z.append(“le”) 会使字符串缓冲区包含 startle ,而 z.insert(4, “le”) 将更改字符串缓冲区,使之包含 starlet 。
StringBuilder(JDK5.0)
StringBuilder:字符串变量(非线程安全)。在内部,StringBuilder 对象被当作是一个包含字符序列的变长数组。
java.lang.StringBuilder 是一个可变的字符序列,是 JDK5.0 新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。
其构造方法如下:
构造方法 | 描述 |
---|---|
StringBuilder() | 创建一个容量为16的StringBuilder对象(16个空元素) |
StringBuilder(CharSequence cs) | 创建一个包含cs的StringBuilder对象,末尾附加16个空元素 |
StringBuilder(int initCapacity) | 创建一个容量为initCapacity的StringBuilder对象 |
StringBuilder(String s) | 创建一个包含s的StringBuilder对象,末尾附加16个空元素 |
在大部分情况下,StringBuilder > StringBuffer。这主要是由于前者不需要考虑线程安全。
三者区别
String 类型和 StringBuffer 的主要性能区别:String 是不可变的对象, 因此在每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,性能就会降低。
使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。所以多数情况下推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。
在某些特别情况下, String 对象的字符串拼接其实是被 Java Compiler 编译成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,例如:
String s1 = “This is only a” + “ simple” + “ test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
生成 String s1 对象的速度并不比 StringBuffer 慢。其实在 Java Compiler 里,自动做了如下转换:
Java Compiler直接把上述第一条语句编译为:
String s1 = “This is only a simple test”;
所以速度很快。但要注意的是,如果拼接的字符串来自另外的 String 对象的话,Java Compiler 就不会自动转换了,速度也就没那么快了,例如:
String s2 = “This is only a”;
String s3 = “ simple”;
String s4 = “ test”;
String s1 = s2 + s3 + s4;
这时候,Java Compiler 会规规矩矩的按照原来的方式去做,String 的 concatenation(即+)操作利用了 StringBuilder(或StringBuffer)的append 方法实现,此时,对于上述情况,若 s2,s3,s4 采用 String 定义,拼接时需要额外创建一个 StringBuffer(或StringBuilder),之后将StringBuffer 转换为 String,若采用 StringBuffer(或StringBuilder),则不需额外创建 StringBuffer。
使用策略
-
(1)基本原则:如果要操作少量的数据,用String ;单线程操作大量数据,用StringBuilder ;多线程操作大量数据,用StringBuffer。
-
(2)不要使用String类的"+"来进行频繁的拼接,因为那样的性能极差的,应该使用StringBuffer或StringBuilder类,这在Java的优化上是一条比较重要的原则。例如:
String result = ""; for (String s : hugeArray) { result = result + s; } // 使用StringBuilder StringBuilder sb = new StringBuilder(); for (String s : hugeArray) { sb.append(s); } String result = sb.toString();
当出现上面的情况时,显然我们要采用第二种方法,因为第一种方法,每次循环都会创建一个String result用于保存结果,除此之外二者基本相同(对于jdk1.5及之后版本)。
-
(3)为了获得更好的性能,在构造 StringBuffer 或 StringBuilder 时应尽可能指定它们的容量。当然,如果你操作的字符串长度(length)不超过 16 个字符就不用了,当不指定容量(capacity)时默认构造一个容量为16的对象。不指定容量会显著降低性能。
-
(4)StringBuilder 一般使用在方法内部来完成类似 + 功能,因为是线程不安全的,所以用完以后可以丢弃。StringBuffer 主要用在全局变量中。
-
(5)相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。而在现实的模块化编程中,负责某一模块的程序员不一定能清晰地判断该模块是否会放入多线程的环境中运行,因此:除非确定系统的瓶颈是在 StringBuffer 上,并且确定你的模块不会运行在多线程模式下,才可以采用 StringBuilder;否则还是用 StringBuffer。
文章来源:https://blog.csdn.net/kingzone_2008/article/details/9220691
14 数组
14.1 一维数组
这里以排序为例子,会涉及到冒泡排序法和Java提供的特殊排序方法
14.1.1 冒泡排序法
从小到大排序:
import java.util.Scanner;
public class Md21 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//从键盘接收数据
System.out.println("输入需要排序的数的个数:");
//输出提示信息
int n = in.nextInt();
//接收需要输入的个数
int[] number = new int[n];
//创建刚好符合存储这些数的数组
int temp=10;
//temp用于后续比较后交换的中间变量(初始值可以不定)
System.out.println("依次输入需要排序的数:");
//输出提示信息
for(int i=0;i<n;i++)
//循环输入需要排序的数(这里i的判断条件用number.length也是一样的)
{
number[i]=in.nextInt();
//将这些输入的数依次存入数组
}
for(int i=0;i<n-1;i++)
//外层循环控制比较的数从第一个开始,到最后一个结束
{
for(int j=0;j<n-i-1;j++)
//内层循环让当前的数number[i]分别于后面的所有数对比
{
if(number[j]>number[j+1])
//如果当然这个数大于它后面的数就进入if语句,将大的数换到后面,小的数换到前面实现排序
{
temp=number[j];
number[j]=number[j+1];
number[j+1]=temp;
}
}
}
System.out.println("从小到大排序如下:");
for(int x : number)
//利用for...Each循环进行输出排序好后的数据
{
System.out.print(x+" ");
}
in.close();
//记得关闭输入
}
}
//输出结果
输入需要排序的数的个数:
10
依次输入需要排序的数:
77 89 45 67 1 104 1212 12 43 24
从小到大排序如下:
1 12 24 43 45 67 77 89 104 1212
当然,从大到小排序也是同理,只需要改变if判断的条件,和交换的顺序就可以实现
import java.util.Scanner;
public class Md21 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//从键盘接收数据
System.out.println("输入需要排序的数的个数:");
//输出提示信息
int n = in.nextInt();
//接收需要输入的个数
int[] number = new int[n];
//创建刚好符合存储这些数的数组
int temp=10;
//temp用于后续比较后交换的中间变量(初始值可以不定)
System.out.println("依次输入需要排序的数:");
//输出提示信息
for(int i=0;i<n;i++)
//循环输入需要排序的数(这里i的判断条件用number.length也是一样的)
{
number[i]=in.nextInt();
//将这些输入的数依次存入数组
}
for(int i=0;i<n-1;i++)
//外层循环控制比较的数从第一个开始,到最后一个结束
{
for(int j=0;j<n-i-1;j++)
//内层循环让当前的数number[i]分别于后面的所有数对比
{
if(number[j]<number[j+1])
//如果当然这个数大于它后面的数就进入if语句,将小的数换到后面,大的数换到前面实现排序
{
temp=number[j+1];
number[j+1]=number[j];
number[j]=temp;
}
}
}
System.out.println("从大到小排序如下:");
for(int x : number)
//利用for...Each循环进行输出排序好后的数据
{
System.out.print(x+" ");
}
in.close();
//记得关闭输入
}
}
//输出结果
输入需要排序的数的个数:
10
依次输入需要排序的数:
77 89 45 67 1 104 1212 12 43 24
从大到小排序如下:
1212 104 89 77 67 45 43 24 12 1
14.1.2 Java提供的特殊排序方法(Arrays.sort()方法)
import java.util.Scanner;
import java.util.*;
public class Md22 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("输入需要排序的数的个数:");
int n = in.nextInt();
int[] number = new int[n];
System.out.print("依次输入要排序的数:");
for(int i=0;i<n;i++)
{
number[i]=in.nextInt();
}
Arrays.sort(number,0,n);
//Java提供的特殊排序方法sort方法,这个方法可以将数组中的数从大到小排序,省去了冒泡排序的两个for循环
//Arrays.sort(数组命,开始的数组下标,结束的数组下标)
//由此可知:我们想完成从大到小排序将0和n换个位置写进方法就可以实现了
System.out.print("从小到大排序如下:");
for(int x :number)
{
System.out.print(x+" ");
}
in.close();
}
}
//输出结果
输入需要排序的数的个数:10
依次输入要排序的数:77 89 45 67 1 104 1212 12 43 24
从小到大排序如下:1 12 24 43 45 67 77 89 104 1212
当然输出时采用倒序输出的方法依然可以得到
虽然这个方法很方便,但是冒泡排序法是算法的一个很经典的思想(也需要熟练掌握)
当然,这个用法的更多解释请点击JAVA中sort()函数的使用方法的个人总结_deansensitive的博客-CSDN博客_java sort方法
sort方法更多的解析Java库中的排序函数_Gransand的博客-CSDN博客_java 排序函数
15 Java方法(函数)
由于是自学,对于Java的方法类还不是很了解,这里就不作多的解释了,等博主开学了,系统的学习了Java后再做总结!!!
16 常见的异常处理
学后总结!!!
参考资料:
置写进方法就可以实现了
System.out.print(“从小到大排序如下:”);
for(int x :number)
{
System.out.print(x+" ");
}
in.close();
}
}
```java
//输出结果
输入需要排序的数的个数:10
依次输入要排序的数:77 89 45 67 1 104 1212 12 43 24
从小到大排序如下:1 12 24 43 45 67 77 89 104 1212
当然输出时采用倒序输出的方法依然可以得到
虽然这个方法很方便,但是冒泡排序法是算法的一个很经典的思想(也需要熟练掌握)
当然,这个用法的更多解释请点击JAVA中sort()函数的使用方法的个人总结_deansensitive的博客-CSDN博客_java sort方法
sort方法更多的解析Java库中的排序函数_Gransand的博客-CSDN博客_java 排序函数
15 Java方法(函数)
由于是自学,对于Java的方法类还不是很了解,这里就不作多的解释了,等博主开学了,系统的学习了Java后再做总结!!!
16 常见的异常处理
学后总结!!!
参考资料: