计算机是一种用于高级计算,使用广泛的设备,主要由计算机硬件和计算机软件两个部分组成
计算机硬件(Computer Hardware)主要包括:中央处理器(CPU)、内存、硬盘、输入输出设备、主板、机箱和电源等辅助设备
CPU:中央处理器(Central Processing Unit),功能主要是解释计算机指令以及处理计算机软件中的数据
内存:内存储器(Memory),用于暂时存放CPU中的运算数据以及与硬盘外部存储器交换的数据。优点是内存中的数据能被CPI直接访问,效率比较高。缺点是内存容量比较小且不能永久存储,一旦断电会造成数据的丢失,因此要记住ctrl+s快捷键进行及时保存
硬盘:主要用于永久存放数据内容,容量大且断电不丢失。CPU不能直接访问硬盘中数据,若希望访问则需要先加载到内存中
输入输出设备
计算机软件(Computer Software)可分为系统软件和应用软件,系统软件就是操作系统,是其他软件的基础。主流的操作系统有Win/Unix(收费)/Linux(免费、开源)/IOS/Android
第一代计算机语言:机器语言,二进制代码,最开始用穿孔卡片
第二代计算机语言:汇编语言,使用助记符表示一条机器指令,如:ADD、SUB等
第三代计算机语言:高级语言,C++、Java等
sun公司 詹姆斯.高斯里 喝咖啡 爪洼岛 Java
桌面应用:
JavaSE(Java Platform,Standard Edition)称之为"Java平台的标准版",是Java平台的基础。JavaSE包含了运行Java应用所需要的基础环境和核心类库。JavaSE定义的基于桌面应用的基础类库可以编写出类似于Office那样丰富多彩的桌面应用。
企业应用:
JavaEE(Java Platform,Enterprise Edition)称之为”Java平台企业版“。JavaEE构建在JavaSE基础之上,用于构建企业级应用。
移动应用:
JavaME(Java Platform,Micro Edition)称之为Java平台微型版。最开始为机顶盒、移动电话和PDA等嵌入式消费电子设备提供Java解决方案。随着以Java为核心编程语言的Android智能平台的迅速普及,JavaME已经走向淘汰。
下载:www.sun.com官网下载或百度搜索官网下载JDK即可(不推荐下载或使用最新版本)
安装:若下载的是安装版,则一路点击下一步安装即可;若下载的是绿色版,则直接解压即可。注意无论安装版还是绿色版的路径都不要有中文!
JDK(Java Development Kit):称为Java开发工具包,Java开发人士需要下载和安装JDK,目前主流版本为JDK11
JRE(JavaSE Runtime Environment):称为JavaSE运行时环境,提供了运行Java应用程序所必须的软件环境等。无论开发还是运行Java应用都必须安装
javac.exe:编译器,主要用于将高级Java源代码翻译成字节码文件
java.exe:解释器,主要用于启动JVM对字节码文件进行解释并执行
JDK、JRE、JVM之间的关系
bin目录 - 该目录下主要存放JDK的各种工具命令
conf目录 - 该目录下主要存放JDK的相关配置文件
include目录 - 该目录下主要存放一些平台的头文件
jmods目录 - 该目录下主要存放JDK的各种模块
legal目录 - 该目录主要存放了JDK各模块的授权文档
lib目录 - 该目录下主要存放了JDK工具的一些补充jar包和源代码(源代码在src.zip压缩包中)
文本编辑器(TE,Text Editor)
集成开发环境(IDE,Integrated Development Environment)
step0、使用Notepad++记得要在设置–>首选项–>新建中将编码改为和DOS属性中一样的编码(默认语言也可以在这里改)
step1、新建文本文档,将文件扩展名由xxx.txt修改为xxx.java
step2、使用文本编辑器的方式打开文件,编写Java代码后进行保存
step3、启动dos窗口,并切换到.java文件所在的路径中(启动dos窗口可以win+R键输入cmd进入后用cd指令进入.java文件所在路径后编译运行;也可以在所在文件夹的路径框中直接输cmd即可打开dos窗口并进入当前所在文件夹)
step4、使用javac xxx.java进行编译(注意这里不能省去后缀),生成xxx.class的字节码文件
step5、使用java xxx进行解释执行(这里不需要文件后缀了),打印最终运行结果
1、拼写错误
2、非法字符:’\uff1b’ —> 通常是因为出现了中文标点符号,要用英文标点符号
在dos窗口中进去.java文件夹后,可以直接使用java xxx.java进行编译运行,打印最终结果(慎用)
ctrl+s保存、ctrl+c复制、ctrl+v粘贴、ctrl+a全选、ctrl+x剪切、ctrl+z撤销、ctrl+f搜索
windows+d回到桌面、windows+e打开计算机、windows+l锁屏、windows+r打开运行,输入cmd后回车就会启动dos窗口、windows+tab切换任务、alt+tab切换任务(用这个)、clt+alt+delete选择启动任务管理器、ctrl+shift+esc直接启动任务管理器
// 单行注释
/* */ 多行注释,注意:多行注释不允许嵌套使用
/** */ 文档注释,是一种支持提取的注释
环境变量基本概念:通常情况下可执行文件(如java.exe)只能在该文件所在的路径中使用,为了使得该可执行文件可以在任意路径中使用,则需要将该文件所在的路径信息配置到环境变量Path中(若我们不配置环境变量要使用javac.exe和java.exe编译执行java代码文件,需将java代码文件放在和这两个可执行文件相同文件夹中)。
配置方式:百度一下,你就知道
注意事项:切记Path变量原来的变量值不要删除(寻找顺序会从前往后依次寻找),配置完毕后记得重启dos窗口
新建名为JAVA_HOME的系统变量:新建变量路径为到bin目录之前,这样是为了以后更新JDK时我们只需要修改JAVA_HOME这个系统变量的路径即可(bin之后的路径所有版本的JDK都是一样的)
Java"一次编译,到处运行"的特点是由JavaVM(Java虚拟机)实现的,通过Java虚拟机,可以实现相同的字节码文件编译成不同的机器指令在不同的系统上运行
变量即“变化的量”。变量可以存放单一数据。声明一个变量的本质是在内存中申请一个存储单元,由于该存储单元中的数据内容可以发生改变,因此称为变量。
定义变量时需要指定变量存储的数据是何种数据类型,不同数据类型的变量在内存中开辟出的内存空间不同。
数据类型 变量名 = 初始值;
/*
编程实现变量的输入和输出
*/
import java.util.Scanner;
public class VarIOTest {
public static void main(String[] args) {
//1、声明两个变量
int age;
String name;
//2、创建一个扫描器来扫描键盘输入的内容,System.in代表键盘输入
Scanner sc = new Scanner(System.in);
//3、通过扫描器读取一个字符串数据放入变量name中
name = sc.next();
//4、通过扫描器读取一个整数放入变量age中
age = sc.nextInt();
//5、打印变量
System.out.println("name = " + name);
System.out.println("age = " + age);
}
}
1.代码的优化
变量随使用随声明(避免先声明变量占用内存空间)
String name = sc.next();
int age = sc.nextInt();
尽可能减少重复代码
System.out.println("name = " + name + "age = " + age);
2.官方库的使用:JDK中带有大量的API类,这些是Java系统带来的工具库,使用这些可以大大简化编程,提高开发效率,具体的API类功能可以参阅Java的参考手册。
Java中数据类型主要有两大类
基本数据类型(记住)
byte、short、int、long、float、double、boolean、char
引用数据类型
数组、类、接口、枚举、标注
十进制(逢十进一,权重为10)、二进制(逢二进一,权重为2,最高位用于表示符号位,最高位为0表示非负数,最高位为1表示负数)、八进制和十六进制(其实都是二进制的简写)
非负数表示范围:0000 0000 ~ 0111 1111 => 0 ~ 127 => 0 ~ 2^7-1
负数表示范围:1000 0000 ~ 1111 1111 => -128 ~ -1 => -2^7 ~ -2^0
单个字节表示的整数范围是:-2^7 ~ 2^7 - 1,也就是-128 ~ 127
Java语言中描述整数数据的类型有:byte(占1个字节,表示范围-2^7 ~ 27-1)、short(占2个字节,表示范围-215 ~ 215-1)、int(占4个字节,表示范围-231 ~ 231-1)、long(占8个字节,表示范围-263 ~ 2^63-1),推荐使用int类型
变量的命名不能是数字开头的,否则可能出现2502505006L这种命名,这是long类型的常量,会混淆。
大的类型转换为小的类型会造成数值损失
int i = 25;
byte b = i; //错误:不兼容的类型:从int转换到byte可能会有损失
浮点类型就是Java中用于描述小数数据的类型:float和double,推荐double类型。
System.out.println(0.1 + 0.2);/*会输出0.30000000000000004,float和double类型运算时可能会有误差,若希望实现精确运算则需要借助java.math.BigDecimal类型*/
Java字符类型采用Unicode字符集编码。Unicode是世界通用的定长字符,所有的字符都是16位。
使用Unicode字符集表示一下“中国”(对应编号\u4e2d \u56fd)两个字:
char c1 = '\u4e2d';
char c2 = '\u56fd';
System.out.println("最终结果是:" + c1 + c2);
自动类型转换主要指从小类型到大类型之间的转换
byte b = 10;
short s = 20;
s = b; //小类型变量b赋值给大类型变量s,实现自动转换
强制类型转换主要指从大类型到小类型之间的转换,语法格式如下:目标类型 变量名 = (目标类型)源类型变量名;
byte b = 10;
short s = 20;
b = (byte)s;
//注意:若s的数据超过byte类型能表示的范围,会造成数据损失(因为只会保留小类型内存空间对应的二进制序列)
当两个整数相除时,结果只保留整数部分,丢弃小数部分;
若希望保留小数部分如何处理?
处理方式一:使用强制类型转换将其中一个操作数转换为double类型再运算即可
System.out.println((double)5 / 2));
处理方式二:让其中一个操作数乘以1.0即可(乘以1.0而不写x.0是因为变量也适用,更通用)
System.out.println(5 * 1.0 / 2);
0不能作除数。
import java.util.Scanner;
public class ArithmeticTimeTest {
public static void main(String[] args) {
//1、提示用户输入秒数,获取该数
System.out.println("请输入一个秒数:");
Scanner sc = new Scanner(System.in);
int time = sc.nextInt();
//2、将正整数的秒数拆分为时分秒后并使用变量记录
int hour = time / 3600;
int min = time % 3600 / 60;
int sec = time % 60;
//3、输出对应的时分秒
System.out.println(time + "秒 = " + hour + "时" + min + "分" + sec + "秒");
}
}
概念:++表示自增运算符,使得当前变量自身的数值加1;–表示自减运算符,使得当前变量自身的数值减1
使用
使用举例
int i = 10;
System.out.println(i++); //此时输出10
System.out.println(i); //此时输出11
System.out.println(++i); //此时输出12
System.out.println(i); //此时输出12
注意:自增减运算符只能用于变量,常数不可以
前自增/自减和后自增/自减的运算结果
格式:条件表达式? 表达式1: 表达式2
使用:判断条件表达式是否成立,成立则执行表达式1,否则执行表达式2
考点一:byte + byte结果还是int类型,这是编译器优化的结果——因为byte + byte很可能直接就超过能表示的范围了,所以编译器直接让它们的结果是int
byte b = 10;
System.out.println("b = " + b); //b = 10;
b = b + 2; //错误:不兼容的类型:从int转换到byte可能会有损失 byte + int 相加还是int类型
b = b + (byte)2; //错误:不兼容的类型:从int转换到byte可能会有损失 byte + byte相加结果还是int //类型,编译器优化
b = (byte)(b + 2); //正确,强制类型转换为byte后再赋值
b += 2; //无报错,真正等价于b = (byte)(b + 2)
System.out.println("b = " + b); //b = 12
考点二
i == 2; //表示判断变量i的数值是否等于2
2 == i; //表示判断2是否等于变量i的数值,结果上来说等价,推荐该方式,因为当我们将==写成=会立刻报错
i = 2; //表示将2赋值给变量i,覆盖变量i原来的数值
2 = i; //编译报错,错误:意外的类型
byte b1 = 13
//b2 = 0000 1101向左移动一位,结果是:0001 1010=26
/*byte b2 = b1 << 1; //错误:不兼容的类型:从int转换到byte可能会有损失 自动提升为int类型,也就是32位二进制*/
byte b2 = (byte)(b1 << 1); //b2 = 26
byte b1 = 13
//b2 = 0000 1101向右移动一位,结果是:0000 0110=6
byte b2 = b1 >> 1; //b2 = 6
byte b2 = b1 >>> 1; //b2 = 6,对于非负数来说,逻辑右移与右移效果一致
byte b1 = 11;
byte b2 = 13;
/*
b1的二进制为:0000 1011
b2的二进制为:0000 1101
*/
System.out.println(b1 & b2); //按位与后的二进制为:0000 1001 =>十进制是9
System.out.println(b1 | b2); //按位或后的二进制为:0000 1111 =>十进制是15
System.out.println(b1 ^ b2); //按位异或后的二进制为:0000 0110 =>十进制是6
System.out.println(~ b1); //按位取反后的二进制数为1111 0100 =>负数二进制转为十进制:先减1得
//1111 0011,再取反0000 1100 =>12,添加符号为-12
当需要进行条件判断并做出选择时,使用分支结构。
if(条件表达式) { 语句块; }
int ia = sc.nextInt();
int ib = sc.nextInt();
int max = ia;
if(ib > max) { //推荐使用这种方式:具有通用性
max = ib;
}
System.out.println("最大值是:" + max);
if(条件表达式) {
语句块1;
} else {
语句块2;
}
条件表达式成立,则执行语句块1;否则执行语句块2。
if(条件表达式1) {
语句块1;
} else if(条件表达式2) {
语句块2;
}
.......
else {
语句块n;
}
满足何种条件就执行哪个语句块;否则执行else中的语句块。
switch(变量/表达式) {
case 字面值1: 语块1; break;
case 字面值2: 语块1; break;
...
default: 语块n;
}
把变量/表达式拿来匹配字面值,匹配到就执行对应语句,遇到break则结束匹配;否则执行default中的语句。
注意:switch()中的是变量/表达式!应该是一个具体值!switch()中支持的数据类型有:byte、short、char以及int类型,从jdk1.5开始支持枚举类型,从jdk1.7开始支持String类型。
循环结构:重复执行某一个步骤(代码),就需要使用循环结构。
任何复杂的程序逻辑都可以通过顺序、分支、循环三种程序结构实现。
for(初始化表达式; 条件表达式; 修改初始值表达式) {
循环体;
}
三种方式实现循环打印奇数
//方式一:根据奇数概念打印
for(int i = 1; i <= 100; i++) {
if(i % 2 != 0) {
System.out.println("i = " + i);
}
}
System.out.println("-----------------------------------------");
//方式二:根据等差数列的概念来打印,每两个数据之间相差2
for(int i = 1; i <= 100; i += 2) {
System.out.println("i = " + i);
}
System.out.println("-----------------------------------------");
//方式三:根据奇数的通项公式规则来打印 2*i-1
for(int i = 1; i <= 50; i++) {
System.out.println("i = " + (2 * i - 1));
}
for循环实现三位数中全部水仙花数的打印
//1、使用for循环打印所有三位数
for(int i = 100; i <= 999; i++) {
//2、拆分三位数上各个数位的数字
int ia = i / 100;
int ib = i % 100 / 10;
int ic = i % 10;
//3、判断是否是水仙花数,是则打印,否则不打印
if(ia * ia * ia + ib * ib * ib + ic * ic * ic == i) {
System.out.println(i);
}
}
break用于退出当前语句块,break用在循环体中用于退出循环。
break关键字一般用在无限循环,也叫做“死循环”。
注意:break只能跳出当前循环,若要退出外层循环体,需要使用标号的方式。
for() {
for() {
break; //只能跳出当前循环
}
}
outer: for() {
for() {
break outer; //能跳出外层outer循环
}
}
while(条件表达式) {
循环体;
}
判断条件表达式是否成立
do{
循环体;
} while(条件表达式); //注意while()后面有分号
先执行循环体,之后判断条件表达式是否成立
int i = 1;
while(i <= 1000); { //这里加分号相当于while循环体为空语句,程序陷入死循环
System.out.println("I Love You");
i++;
}
基本类型的数组(数据元素为基本类型)创建后,其元素的初始值:byte、short、char、int、long为0;float和double为0.0;boolean为false
两种方式进行数组的初始化
静态方式:可以在数组声明的同时进行初始化,具体如下
数据类型[] 数组名称 = {初始值1,初始值2,…};
int[] arr1 = {1, 2}; //静态方式的简化版
int[] arr2 = new arr2[]{1, 2}; //静态方式的完整版,注意静态声明完整版后面[]不要声明数组长度!
动态方式:使用循环遍历数组一个一个进行赋值初始化
基本数据类型将值直接放在栈区域;而引用数据类型在栈区域中存储的是地址,由该地址索引到堆区域中对应地址的值才是引用数据类型的值,也因此输出数组名输出的是栈区中存储的地址而不是具体值。
//1、增加:创建一个长度为5的一维数组,给数组的前4个元素分别赋值11 22 33 44
int[] arr = new int[5];
for(int i = 0; i < arr.length - 1; i++) {
arr[i] = (i + 1) * 11; //11 22 33 44 0
}
//2、插入:在0位置插入一个数字55(其实就是顺序表的插入操作)
for(int i = 4; i > 0; i--) {
arr[i] = arr[i - 1];
}
arr[0] = 55;
//3、删除:将元素55从数组删除,删除方式为后续元素向前移动,最后位置置为0并打印(其实就是顺序表的 //删除操作)
for(int i = 1; i < arr.length ; i++) {
arr[i - 1] = arr[i];
}
arr[arr.length - 1] = 0;
//4、查找:查找数组中是否存在元素22,若存在则修改为220后再次打印所有元素
for(int i = 0; i < arr.length; i++) {
if(arr[i] == 22) {
arr[i] = 220;
break; //只要找到就可以退出循环
}
}
//输出数组
for(int i = 0; i < arr.length; i++) {
System.out.println("arr[" + i + "] = " + arr[i]);
}
方式一:自己写
for(int i = 0; i < brr.length; i++) {
brr[i] = arr[i + 1]; //将arr从位置1开始的元素拷贝到brr数组中
}
方式二:使用java.base.lang.System中的arraycopy()方法
System.arraycopy(arr, 1, brr, 0, 3); //实现结果同方法一
一维数组之间拷贝的笔试考点
brr = arr; //将arr数组栈内存中存储的地址赋值给brr,brr就指向了arr数组在堆内存中存储的元素堆
static String toString(int[] a) //输出数组中的内容
System.out.println("第一个数组中的元素有:" + Arrays.toString(arr));
static void fill(int[] a, int val) //将val赋值给数组中所有元素
Arrays.fill(arr2, 10); //将arr2中的所有数组元素填充为10
static boolean equals(boolean[] a, boolean[] a2) //判断两个数组元素内容和次序是否相同
System.out.println(Arrays.equals(arr2, arr3)); //判断arr2与arr3是否完全相同,若完全相同则打印true,否则打印false。(注意内容和次序都要完全相同)
static void sort(int[] a) //对数组中的元素进行从小到大排序
Arrays.sort(arr); //从小到大排序
static int binarySearch(int[] a, int key) //从数组中查找值为key的元素所在位置,不存在则返回一个越界下标(负数)
System.out.println(Arrays.binarySearch(arr, 3)); //查找元素值为3所在下标
关于数组的长度
遍历二维数组:使用外层for循环遍历二维数组的行,内层for循环遍历二维数组的列
for(int i = 0; i < arr.length; i++) {
for(int j = 0; j < arr[i].length; j++) {
...; //循环体内可以进行初始化及其他一些对数组元素的操作
}
}
二维数组的初始化
//1、提示用户输入一个行数并用变量记录
System.out.println("请输入杨辉三角需要的行数:");
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
//2、根据用户输入的行数来声明对应的二维数组存储杨辉三角
int[][] yanghui = new int[num][];
//3、根据杨辉三角的特点对二维数组进行初始化
for(int i = 0; i < yanghui.length; i++) {
//注意:要记得针对数组中的每一行进行内存空间的申请
yanghui[i] = new int[i + 1];
//使用内层for循环控制二维数组的列下标
for(int j = 0; j <= i; j++) {
//当列下标为0或者和行相同时,
if(j == 0 || j == i) {
yanghui[i][j] = 1;
} else {
//否则对应位置元素的值就是上一行当前列的值加上上一行前一列的值
yanghui[i][j] = yanghui[i - 1][j] + yanghui[i - 1][j - 1];
}
}
}
//4、输出杨辉三角查看效果
for(int i = 0; i < yanghui.length; i++) {
for(int j = 0; j <= i; j++) {
System.out.print(yanghui[i][j]);
}
System.out.println();
}
外层for循环遍历二维数组的行,内层for循环遍历二维数组的列
for(int i = 0; i < arr.length; i++) {
for(int j = 0; j < arr[i].length; j++) {
...; //循环体内可以进行初始化及其他一些对数组元素的操作
}
}
二维数组的初始化
//1、提示用户输入一个行数并用变量记录
System.out.println("请输入杨辉三角需要的行数:");
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
//2、根据用户输入的行数来声明对应的二维数组存储杨辉三角
int[][] yanghui = new int[num][];
//3、根据杨辉三角的特点对二维数组进行初始化
for(int i = 0; i < yanghui.length; i++) {
//注意:要记得针对数组中的每一行进行内存空间的申请
yanghui[i] = new int[i + 1];
//使用内层for循环控制二维数组的列下标
for(int j = 0; j <= i; j++) {
//当列下标为0或者和行相同时,
if(j == 0 || j == i) {
yanghui[i][j] = 1;
} else {
//否则对应位置元素的值就是上一行当前列的值加上上一行前一列的值
yanghui[i][j] = yanghui[i - 1][j] + yanghui[i - 1][j - 1];
}
}
}
//4、输出杨辉三角查看效果
for(int i = 0; i < yanghui.length; i++) {
for(int j = 0; j <= i; j++) {
System.out.print(yanghui[i][j]);
}
System.out.println();
}