Java的基本程序设计结构(未完)
参考价值:未完成,较为臃肿、没有错误,短时间不会重置,不建议参考,可以作为工具查找信息(但更建议用课本)
注释
//注释(单行注释)
1
2
3
4
5
6
7
8public class HelloWorld
{
public static void main(String[] args)
{
//打印Hello World!
System.out.println("HHello World!");
}
}/* 注释 */(多行注释)
1
2
3
4
5
6
7
8
9
10/*
这个程序的作用是打印一个Hello World
*/
public class HelloWorld
{
public static void main(String[] args)
{
System.out.println("HHello World!");
}
}文档注释
数据类型
整型
用途:在内存中划出一定大小的空间来储存一个整数
类型 | 储存需求 | 取值范围 |
---|---|---|
int | 4字节 | -2 147 4833 648~2 147 4833 647 |
short | 2字节 | -32 768~32 767 |
long | 8字节 | -9 233 372 036 854 775 808~-9 233 372 036 854 775 807 |
byte | 1字节 | -128~127 |
Java与C / C++的区别:
Java不如C / C++效率高,但可移植性更强:
和Java不同,C / C++中整型数据的储存需求不是固定的,而是根据操作系统的不同选择最高效的范围。因此,C/C++对内存的利用效率是要大于Java的。但一个在32位系统上运行的C/C++程序在16位系统上运行时会发生整数溢出的情况,因此移植性较差。而Java因为兼顾了移植性,所以才采取所有平台固定储存需求的方式,这也导致在一些内存极为珍贵的情况下,更倾向于使用C/C++来编写程序。
Java整型是不存在任何无符号(unsigned)形式的:
如题。其实Java也是能够使用无负数的整形的,但实际操作起来必须相当仔细。初学者不必考虑,知道即可。
浮点类型
用途:在内存中划出一定大小的空间来储存一个带小数的数
类型 | 储存需求 | 取值范围 |
---|---|---|
float | 4字节 | 有效位数6~7位 |
double | 8字节 | 有效位数15位 |
单精度浮点型和双精度浮点型的由来
float和double也分别被称为单精度浮点型和双精度浮点型,这是因为double的数值精度是float的两倍。
char类型
用途:在内存中划出一定大小的空间来储存一个字符
类型 | 储存需求 |
---|---|
char | 2字节 |
boolean类型
即布尔类型,只有两个值:false和true,用来判定逻辑条件。且在Java中,整型值不能和布尔值交换。
变量与常量
声明变量
使用变量前必须要先声明变量。
1 | /* |
*补充概念
关键字
即在Java中有特殊作用的字,比如:int / double / char 等。
保留字
之现在版本中没有作为关键字但在以后版本中会成为关键字的字。
标识符
自己起的名字都叫标识符,比如:变量名、方法名、类名等
标识符不能是关键字或保留字。
- 标志符命名规则
- 只能由英文字母,0~9,下划线_或 $ 组成。
- 单下划线 _不能作为标识符
- 标识符开头不能是数字
- 标识符不能是关键字或保留字
- 标志符命名规则
变量初始化
对声明的变量必须进行初始化后再使用。
1 | /* |
- 在Java中,变量的声明需要尽可能接近第一次使用的地方
关键字var
var :是 一种动态类型。对于局部变量,当可以从变量的初始值判断出数据类型时。就不用声明类型,直接使用关键字var即可。
1 | var grace=100;//grace的类型是整型 |
常量
只能被赋值一次就不能修改的量叫做常量。
1 | /* |
枚举类型
未完待续 . . .
运算符
算术运算符
算术运算符 | 意义 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 求余 |
除法:
- / 两边的数据都是整数时,为整数除法,否则为浮点除法
除以0
当整数除以0时,程序会出现异常
当浮点型数据除以0时,会显示无穷大或者NaN
数学函数与常量
在实际应用中,数据之间的运算并不是简简单单靠算术运算符完成的。很多复杂或者特殊的运算是依靠Math库里的各种函数来实现的。合理运用Math库里的数学函数运算能够有效的提高代码的效率。
首先,先上代码:
1 | /* |
pow函数
1
2
3
4//语法:
pow(x,n);
//作用:
计算x的n次方注意:pow( )的返回值必须是double类型
sqrt函数
1
2
3
4//语法:
sqrt(x)
//作用:
计算x的算术平方根sqrt的返回值也必须是double
floorMod
1
2
3
4//语法:
floorMod(被除数,除数)
//作用:
取模运算和%的区别
挖个坑,以后再填(doge)
直接引用数学函数
在源文件顶部加上这行代码即可:
1
import static java.lang.Math.*;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import static java.lang.Math.*;
public class Mathematicalfunction{
public static void main(String[] args){
double number1=pow(4.0,3.0);
System.out.println("4的3次方是:"+number1);
double number2=sqrt(4.0);
System.out.println("4的算术平方根是:"+number2);
int number3=floorMod(-7,3);
System.out.println("-7除以3的余数是:"+number3);
double number4=sin(PI/3);
System.out.println("60°的正弦是:"+number4);
double number5=cos(PI/3);
System.out.println("60°的余弦是:"+number5);
double number6=tan(PI/3);
System.out.println("60°的正切是:"+number6);
}
}
数值类型之间的转换
数值类型之间存在的合法转换
实线箭头的类型转换不会有信息丢失,但虚线箭头的类型转换可能会导致信息缺失,精度降低。
1 | public class Change{ |
强制类型转换
先看一个例子:
1 | public class Bad{ |
像这种一定会损失精度的转换,在Java中是不合法的。但在有些情况下,我们又不得不进行这样的转换。所以Java为我们提供了强制类型转换的方法。
1 | public class Bad{ |
但是强制类型转换是直接砍掉后面的数字。要想在类型转换时四舍五入,需要借助数学函数round:
1 | public class Bad{ |
警告:
如无必要,最好不要使用强制类型转换,使用强制类型转换有时候能造成数值被劫夺为一个完全不同的值。
1 | public class Bad{ |
结合赋值和运算符
是对赋值和运算符的一种简写。比如:
1 | x=x+4;可以简写成x+=4;//所有算术运算符都可以这么做 |
注意:
如果运算符得到一个值,并且与左侧的操作数类型不同则会发生强制转换,把运算符的值强制转换为左边操作数的值,而且是直接截断,比如:
1 | public class Strong{ |
自增和自减运算符
由于在平时开发中,变量加一或减一都很常见。所以,java就借鉴了C / C++,推出了自增和自减运算符,即++,–。
1 | x=x+1;可以转换为x++;//当++的位置不同时,其运算方式也会发生不同。int m=8;int n=8;int x=2*++m;//x=18,m=9int y=2*n++;//x=16,m=9 |
关系和boolean运算符
关系运算符有大于( > )、小于( < )、大于等于( >= )、小于等于( <= )、等于( = ).它们的值为true / false(boolean类型)。
逻辑运算符有&&、||、!=,具体用法和C / C++一样。
java 也支持 ? : 三元运算符,x?a:b;
即若x为true则表达式的值为a,否则为b.
1
2
3
4
5
6
7
8public class Three{
public static void main(String[] args){
int x=4;
int y=3;
int number=x<y?100:666;
System.out.println(number);
}
}
位运算符
学习位运算符之前我们要先了解计算机二进制和一些偏底层的相关知识
数据是如何被储存在计算机的?
计算机中能够储存数据的硬件只有内存和存储设备(以下统称内存),然而数据是怎么存入其中的呢?所有的数据都是有类型的,比如整型、浮点型、char型、String型等。当我们要存储数据10时,我们首先要声明变量,其次把10放进这个变量里(其实就是变量赋值),就完成了数据的储存。然而,深入到底层硬件层次,这一通操作是怎么实现的呢?
1 | int number;//声明变量//在内内存中划出一块4个字节大小的空间口口口口口口口口 口口口口口口口口 口口口口口口口口 口口口口口口口口 口口口口口口口口,命名为number。number=10;//变量赋值//编译器把10转换为二进制1010,然后把二进制的10储存在number空间里,即0000 0000 0000 1010.//这样,一个数据就成功地存入内存里了。 |
二进制
有符号数 / 无符号数
有符号数
有符号数就是指一个变量既可以存储正数,也可以存储负数。这是因为有符号数的二进制首项是符号位。比如:
1
int number1=10;//它储存在空间里的样子是:00000000 00000000 00000000 1010int number2=-10;//它储存在空间里的样子是:10000000 00000000 00000000 00001010
无符号运算符
无符号数是指只能存放正数不能存放负数,其原理就是去掉了符号位,这样可以使一个变量能够存储更大的数。比如:C / C++中的unsigned int 等。
正负数的源码、反码、补码
正数
源码、反码、补码都一样。
负数
反码=符号位不变,其他位取反(即1->0,0->1)
补码=反码+1
0的反码补码都是0
关于十六进制
十六进制和二进制刚好有四对一的关系。为了不占用太大的空间,在书写记录时,一般我们用十六进制来书写二进制。
二进制 十六进制 0000 0 0001 1 0010 2 0011 3 0100 4 0101 5 0110 6 0111 7 1000 8 1001 9 1010 A 1011 B 1100 C 1101 D 1110 E 1111 F 比如说:
1
int number=127;//m=0000 0000 0000 0000 0000 0000 0111 1111(二进制源码)->0000 007F(十六进制源码)
逻辑运算符和位移运算符
提醒,计算机用位运算符计算数据是都是按补码计算的。
逻辑运算符
与运算符(&)
1
2
3
4
5
6
7
8
9
10
11
12public class Count{
public static void main(String[] args){
int m=15;//n=0000 0000 0000 0000 0000 0000 0000 1111->0000 0000 0000 0000 0000 0000 0000 1111(补码)(为了简洁表达,之后的源码和补码会省略中间的0或1)
int n=127;//m=0000 0111 1111->0000 0111 1111(补码)
int number1=n&m;//number=0000 1111->0000 1111(补码)
System.out.println(number1);//number=15
int x=15;//x=0000 1111->0000 1111(补码)
int y=-127;//y=1000 0111 1111->1111 1000 0001(补码)
int number2=x&y;//number2=00000001->0000 0001(补码)
System.out.println(number2);//number2=1
}
}&的规则是对应位两个都为1,则结果取1,否则都取0.
或运算符(|)
1
2
3
4
5
6
7
8
9
10
11
12public class Count{
public static void main(String[] args){
int m=15;//n=0000 1111->0000 1111(补码)
int n=127;//m=0000 0111 1111->0000 0111 1111(补码)
int number1=n|m;//number=0000 0111 1111->0000 0111 1111(补码)
System.out.println(number1);//number=127
int x=15;//x=0000 1111->0000 1111(补码)
int y=-127;//y=1000 0111 1111->1111 1000 0001 (补码)
int number2=x|y;//number2=1000 0111 0001->1111 1000 1111(补码)
System.out.println(number2);//number2=-113
}
}| 的规则是对应位两个都为0,则结果取0,否则都取1.
非运算符(~)
1
2
3
4
5
6
7
8
9
10public class Count{
public static void main(String[] args){
int m=15;//n=0000 1111->0000 1111(补码)
int number1=~m;//number=1000 0001 0000->1111 1111 0000(补码)
System.out.println(number1);//number=-16
int x=-15;//x=1000 1111->1111 0001(补码)
int number2=~x;//number2=0000 1110->0000 1110(补码)
System.out.println(number2);//number2=14
}
}~ 的规则是每一位都取反。
异或运算符(^)
1
2
3
4
5
6
7
8
9
10
11
12public class Count{
public static void main(String[] args){
int m=15;//n=0000 1111->0000 1111(补码)
int n=127;//m=0000 0111 1111->0000 0111 1111(补码)
int number1=n^m;//number=0000 0111 0000->0000 0111 0000(补码)
System.out.println(number1);//number=112
int x=15;//x=0000 1111->0000 1111(补码)
int y=-127;//y=1000 0111 1111->1111 1000 0001 (补码)
int number2=x^y;//number2=1000 0111 0010->1111 1000 1110(补码)
System.out.println(number2);//number2=-114
}
}^ 的规则是对应位相同取0,不同取1
位移运算符
左移运算符(<<)
1
2
3
4
5
6
7
8
9
10
11
12public class Count{
public static void main(String[] args){
int x=15;//x=0000 1111->0000 1111(补码)
int y=-15;//y=1000 1111->1111 0001(补码)
int number1=x<<1;//number1=0000 0001 1110->0000 0001 1110(补码)
System.out.println(number1);//number1=30
int number2=y<<1;//number2=1000 0001 1110->1111 1110 0010(补码)
System.out.println(number2);//nuber2=-30
int number3=x<<33;//number3=0000 0001 1110->0000 0001 1110(补码)
System.out.println(number3);//number3=30
}
}<<运算符的规则是:当x<<n时,所有对应位左移x%32位,右端补0,左端溢出的丢弃。(大部分时候等同于*2的x%32次方)
右移运算符(>>)
1
2
3
4
5
6
7
8
9
10
11
12public class Count{
public static void main(String[] args){
int x=15;//x=0000 1111->0000 1111(补码)
int y=-15;//y=1000 1111->1111 0001(补码)
int number1=x>>1;//number1=0000 0001 1110->0000 0111(补码)
System.out.println(number1);//number1=7
int number2=y>>1;//number2=1000 1000->1111 1000(补码)
System.out.println(number2);//nuber2=-8
int number3=x>>33;//number3=0000 0111->0000 0111(补码)
System.out.println(number3);//number3=7
}
}.>>运算符的规则是:当x>>>n时,所有对应位右移x%32位,左端端正数补0、负数补1,右端溢出的丢弃。
无符号右移运算符(>>>)
1
2
3
4
5
6
7
8
9
10
11
12public class Count{
public static void main(String[] args){
int x=15;//x=0000 1111->0000 1111(补码)
int y=-15;//y=1000 1111->1111 0001(补码)
int number1=x>>>1;//number1=0000 0001 1110->0000 0111(补码)
System.out.println(number1);//number1=7
int number2=y>>>1;//number2=0111 1000->0111 1000(补码)
System.out.println(number2);//nuber2=2147483640
int number3=x>>>33;//number3=0000 0111->0000 0111(补码)
System.out.println(number3);//number3=7
}
}.>>>的规则是:当x>>>n时,所有对应位右移x%32位,左端补0,右端溢出的丢弃。
字符串
Java没有字符串类型,而是在标准Java类库中提供了一个预定义类来使用字符串,也就是String
简单示例:
1 | public class Strings{ |
子串
String类中的substring方法可以从字符串中提取一个子串。
1 | public class Strings{ |
name.substring(m,n) 中m是起始字符位置n是终止字符位置,且取n不取m。(注:0是第一个)
拼接
和绝大多数语言一样,java语言中字符串是可以通过+号对字符串进行连接的。
1 | public class Strings{ |
当字符串和非字符串连接时,非字符串会被转换成字符串并和字符串进行拼接,常见的例子比如输出语句:
1 | System.out.println("我已经"+age+"岁了");//age=20 |
填充
这个用的比较少,是静态方法join的方法。当我们把多个字符串连接在一起并用一个界定符分割时,我们可以用 join 实现。
1 | public class Strings{ |
当然我们也不一定非要加界定符,可以尽可能的发挥我们的想象力。
1 | public class Strings{ |
复制
有些时候我们需要复制很多相同的字符串然而我们也不能傻乎乎的把一个字符串输入几百上千次。Java11中提供了一个repeat方法来解决这个问题。
1 | public class Strings{ |
不可变字符串
在Java中String类是不允许单独修改一个字符串中的某个字符的,我们一般可以通过提取字串加拼接的方式来构造新的字符串。
1 | public class Strings{ |
检查字符串是否相等
要想检查两个字符串是否相等需要使用equals方法,相同返回true,不同返回false。
1 | public class Strings{ |
如果不想区分大小写可以用equalsIgnoreCase方法:
1 | public class Strings{ |
不要用==来检查字符串是否相等,只有当两个字符串相同并且位置相同时才会返回true,否则返回false。
1 | public class Strings{ |