java语言基础
初识计算机和java语言
1.计算机由硬件和软件组成
计算机中的主要硬件
- cpu
是计算机中最核心的部件,类似人的大脑
一台计算机的运算核心和控制核心都由cpu完成
其主要功能是解释计算机的指令以及处理计算机软件中的数据
ps 端cpu主要是intel和amd在生产
移动端处理器 高通骁龙 华为麒麟 苹果 a系列
- 内存
内存也被称为内储存器
用于暂时储存cpu中的运算数据以及与硬等外部储存器交换数据
cpu可以直接访问内存 而且效率很高
容量小不能实现永久储存,一旦断电和造成数据丢失
时刻记得ctrl+s将数据放到硬盘中
- 硬盘
计算机中的储存设备
主要用于永久储存数据 容量大 断电不会丢失
cpu不能直接访问硬盘中的数据 若要访问需要先加载到内存中
- 输入输出设备
其中键盘叫标准输入设备,显示器叫标准输出设备
常见的软件
分为系统软件和应用软件
主流操作系统:windows unix linux (移动端)ios android
计算机体系结构
为什么硬盘的内存在买回后回比标注的少
硬盘的生产厂家在生产硬盘的时候会以1000作为换算单位,及1000m为1g 最后在电脑上计算机以1024作为1g进行换算
java语言的主要版本
javaEE是建立在javaSE的基础上
相关概念
javac.exe--编译器 负责将高级语言java的源代码翻译成字节码
java.exe--解释器 用于启动jvm对字节码进行解释并执行
编写java程序的流程
- 新建文本文档,将文件的扩展名改为.java
- 使用记事本notepid++打开文件,编写java代码后进行保存
- 启动dos窗口,并切换的java文件所在的路径
- 使用javac xxx.java进行编译,生成xxx.java的字节码文件
5.使用java xxx进行解释执行,打印最终的结果
编写java程序的流程
- 编程习惯:1遇到做左括号的下一行代码,一般空一行再缩进
2 右花括号始终和左化括号所在行的第一个单词对齐
3.main方法为程序的入口
启动dos窗口并切换java文件所在的路径的方法
- 点击空白处 按住shif+鼠标右键 powershell窗口
2.将文件所在目录改成cmd即可
dos命令:cls清理屏幕
java代码中常见的错误
通常出现多个错误,找第一个报错
该方法问题很大
常见的快捷键
java跨平台原理
java 字节码可以通过JVM翻译成具体平台能够执行的机器指令,sun公司定义了JVM的规范,而且不同的操作系统大多提供了JVM的实现,使得相同的字节码客园在不同的系统上运行
变量的概念
变量的数据类型决定了其所占的存储单元的大小
变量名
标识符的命名规范
在开发中一般以字母命名
常用的进制
二进制中最高位代表符号位,0表示非负数 1表示负数
十进制转换为二进制------拆分法
负的十进制转换为二进制*
1.先将十进制的绝对值转换为二进制
2.将此二进制取反 然后+1
负二进制转为十进制
和前面的过程相反
单个字节表示的范围为 -128---127
整数类型的概念
在开发中推荐用int类型
整型的应用
/*
编程实现整数类型的应用
*/
public class IntTest{
public static void main(String[]args){
1.byte a=25;//此处也存在int-->byte 但25在byte的数据范围内 编译器帮我们优化(仅为字面量的时候适用)
//没有报错
System.out.println(a);
byte b=250; //不兼容的类型: 从int转换到byte可能会有损失
//250这种直接写出来的整数数据叫直接量/常量/字面量 默认文Int类型
//从int -->byte 转换会损失精度而报错
System.out.println(a);
}
}
int a =25;
byte i=a;//和1.处对比,虽然也是int-->byte但右值为变量,编译器不能帮我们优化
浮点数的概念
- float 表示的有效数字位为7位
- double 表示的有效数字位为15位
浮点型编程的使用
public class DoubleTest{
public static void main(String[]args){
float a=3.1415926456;//1.对于直接写出来的浮点型数据默认位double,可以写后缀改变
//2.存在double-->float 造成数据损失
//3.float 类型只保证只保证7位有效数字的准确,后面不保证
System.out.println("a="+a);
double b=3.1415926456;//这里就不会报错
}
}
笔试考点
1.浮点型数据不能实现精确运算,若需要精确运算(比如算金钱)可以用 java.math.BigDecimal
布尔类型的概念和运用
/*
boolean类型的应用
*/
public class BooleanTest{
public static void main(String[]args){
boolean a=false;
boolean b=true;
System.out.println("a="+a+"b="+b);
boolean c=0;//将会报错 int不能转化为boolean
}
}
字符类型的概念
- char 中计算机内占2个字节 ,并且没有符号位
- 所表示的范围是0-65535
字符的存储
在计算机中为了储存字符,可以给字符一个编号,然后将编号存储起来,这个编号叫ascii,实现间接存储
需要掌握的ASCII ‘0’---48 ‘a'---97 'A'---65 空格---32 换行符---10
char的应用(重要)
1.char 类型在计算机底层中实际上是储存其ASCII码,在最底层实际为ASCII码对应的二进制
对其的打印实际上取决于对其的解析方式
2.
/*
编程实现char类型的使用
*/
public class CharTest{
public static void main(String[]args){
char c='a';
System.out.println(c);//该方式字符按字符解析 打印出字符
System.out.println((int)c);//该方法字符按ASCII解析 打印出ASCII
char a=98;//图案在底层就是整数编号,直接给整数编号没问题 该处和数据类型转换无关
int b='a';//字符在底层就是整数类型,直接赋值给int 没有问题
}
}
unicode字符集的概念和使用
- java字符集采用unicode字符集编码,为世界定长字符集,所以字符占16位
- unicode和ASCII是兼容的,可以将unicode想象成ASCII的扩展版
- 可以看成unicode和ASCII一样
/*
编程实现char类型和unicode字符集的使用
*/
public class CharTest{
public static void main(String[]args){
char c='a';
//System.out.println(c);//该方式字符按字符解析 打印出字符
//System.out.println((int)c);//该方法字符按ASCII解析 打印出ASCII
char a=98;//图案在底层就是整数编号,直接给整数编号没问题 该处和数据类型转换无关
int b='a';//字符在底层就是整数类型,直接赋值给int 没有问题
//unicode是ASCII的扩展版 兼容ASCII
//虽然unicode看样子是字符集,但可以看成和ascii一样
//\u77f3\u6587\u6d9b
char s='\u77f3';
char w='\u6587';
char t='\u6d9b';
int g='\u6d9b';
//System.out.println("你的姓名是:"+s+w+t);
//System.out.println(g);
}
}
转义字符的概念和使用
//将原本的含义转换为该含义自身
//对于java代码中一些特殊字符 含义表示(以"为例)
//1.表示字符串的开头和结尾 2.表示 该”本身
//系统和默认为第一种含义,如果要表示第二种含义则需要转义
public class SpecialCharTest{
public static void main(String[]args){
System.out.println("我想过过\"过过的生活");//该“如果不转义 计算机识别不了
}
}
自动类型转换和使用
(注意:从long--->float 的易错点 .主要和float和底层存储有关,及表示范围)
/*
实现基本数据类型转换的应用
*/
public class TypeChageTest{
public static void main(String[]args){
byte a=3;
short b=4;
b=a;//a由byte-->short 由小范围-->大范围 为自动转换 因为不会损失精度
System.out.println(b);
}
}
强制类型的转换
/*
用于测试强制类型转换
*/
public class Casting{
public static void main(String[]args){
//情况一
short a=45;
byte b=(byte)a;//此种情况,a的值在byte的范围中,不会出现数据损失
System.out.println(b);
//情况二
short c=128;
byte d=(byte)c;
System.out.println(d);//short c 的128在byte中放不下,会造成数据损失
//输出为-128
}
}
过程的证明:
算术运算符
基本一致 略
字符串连接符的概念和使用
/*
测试字符串连接符+的作用
*/
//+既可以是加号运算符又可以是字符串连接符
//判断方法:当+两边至少有一个是字符串类型则+为字符串连接符,否则为加号运算符
public class StringLink{
public static void main(String[]args){
int a=3;
int b=5;
int c=6;
System.out.println(a+b+c);//14
System.out.println(a+b+c+"");//14
System.out.println(a+b+""+c);//86
System.out.println(a+""+b+c);//356
System.out.println(""+a+b+c);//356
System.out.println(""+(a+b+c));//14
}
}
自增自减运算符
/*
自增自减运算符的运算顺序
*/
public class SelfTest{
public static void main(String[]args){
//规律总结:i++ 中i为操作数 ++为操作符 i++为表达式
//++i 表示先让变量+1 然后让变量的值作为表达式的结果
//i++ 表示先让变量的值作为表达式的结果,在让变量加1
int a=6;
System.out.println(a);//6
System.out.println(a++);//6//实际是要输出表达式的值
System.out.println(a);//7
System.out.println(++a);//8
System.out.println(a);//8
int b=6;
int c=8;
//实际为变量+1的数值是否作为表达式的值
System.out.println(a+b+c);//22
System.out.println(a+++b+c);//22
System.out.println(a+b+c);//23
System.out.println(++a+b+c);//24
}
}
逻辑运算符
逻辑运算符要求两边的操作数或者两边的表达式都必须是boolean类型
逻辑运算符的短路特性
- 对于逻辑与运算符 第一个表达式为假则 整体为假,则会跳过第二个表达式的判断
- 对于逻辑或运算符 第一个表达式为真 则整体为真 则会跳过第二个表达式的判断
/*
验证逻辑运算符的短路特性
*/
public class ShortCircuit{
public static void main(String[]args){
int a=3;
int b=5;
//逻辑与第一个表达式为假 则跳过第二个表达式不执行
boolean c=(++a==3)&&(++b==5);
System.out.println("c="+c);//false
System.out.println("a="+a);//4
System.out.println("b="+b);//5
//逻辑或第一个表达式为真 则跳过第二个表达式不执行
// 举例略
}
}
三目运算符
以实际执行表达式的值作为三目表达式整体的值
赋值运算符
赋值表达式本身也有值,其本身之值即为所之值的值
赋值表达式面试题----编译器优化类型转换
/*
阐述下面2个表达式的区别
*/
public class Main {
public static void main(String[]args){
byte b=5;
//表达式1
//b= b+2; //不兼容的类型: 从int转换到byte可能会有损失
//对错误的理解1:以为2为字面量 默认为Int 和b运算为int 向byte转换报错(理解有误)
//表达式2 //正解:实际上这是编译器的一个优化,对于2个小类型的运算,编译器会将其结果转换为int
//防止溢出 (byte short char之间都会这样)
b+=2;
//这2个表达式实际上不完全相等b+=2等价于b=(byte)b+2 已经提前转换
}
}
//编程经验
a==2;
2==a;//推荐这一种写法
//用这种写法 少写一个=时 ,编译器会报错
移位运算符(了解)
应用:
/*
编程实现移位运算符的使用
*/
public class MoveBitTest{
public static void main(String[]args){
//左移为将整数二进制往左移动一位 右边补零
byte a=13;
//byte b=a<<1;数据不兼容 编译器将左移的答案优化为int
byte b=(byte)(a<<1);
System.out.println(b);
//左移规律 左移一位相当于当前整数*2
//左移2位相当于整数*4
int d=20;
//右移二进制往右移动一位左补符号位
byte c=(byte)(d>>1);
System.out.println(c);
System.out.println(c>>1);
//右移规律:右移一位相当于当前整数/2
//右移2位相对于当前整数/4
//逻辑右移对于非负数来说 和右移是一样的
}
}
位运算符
对于& \ ~(取反)和逻辑运算符的相比较 只是按照 位进行
^相同为真不同为假
位运算符的使用
计算个人所得税
*个人应纳税所得额(本金-不用纳税部分) 对应税率-速算扣除数
/*
利用switch case模拟菜单系统
*/
import java.util.Scanner;
public class SwitchMenuTest{
public static void main(String[]args){
Scanner st=new Scanner (System.in);
System.out.println(" 欢迎来到拉钩教育");
System.out.println("---------------------------------");
System.out.print(" [1]学员系统 [2]管理员系统\n");
System.out.println(" [0]退出系统");
System.out.println("---------------------------------");
System.out.println("请选择要进入的系统:");
int choose=st.nextInt();
switch(choose){
case 1:System.out.println("正在进入学员系统....");break;
case 2:System.out.println("正在进入管理员系统...");break;
case 0:System.out.println("正在退出系统...");break;
}
}
}
for循环实现猜数字的游戏
/*
用for循环实现猜数字游戏
*/
import java.util.Random;//用于生成随机数
import java.util.Scanner;
public class ForGuessTest{
public static void main(String[]args){
Random ra=new Random();
Scanner st=new Scanner(System.in);
int res=0;//评定等级
//将随机生成的数对100取余
int tem=ra.nextInt(100)+1;//生成一个1-100的随机变量
System.out.print("欢迎来到猜数字!");
System.out.println("将随机生成一个1-100的随机数,请猜出这个数字");
while(true){
System.out.println("请输入你猜测的数字:");
int num=st.nextInt();
res++;
if(num>tem)System.out.println("猜大了,再小一点");
else if(num<tem)System.out.println("猜小了,再大一点");
else{
System.out.println("恭喜你猜对了!");
break;
}
}
if(res==1)System.out.println("你已经独孤求败了!");
else if(res>1&&res<=6)System.out.println("你还真有两把刷子!");
else System.out.println("你水平一般啊!继续努力吧!");
}
}
找素数
/*
使用双重for循环打印2-100之间的所有素数
*/
//素数:除了1和本身外没有其余的因数
public class ForPrimeTest{
public static void main(String[]args){
for(int i=2;i<=100;i++){
boolean flag=true; //标记是否为素数
for(int j=2;j<=i/2;j++){//这是一个优化
if(i%j==0){
flag=false;//更新不为素数
break;
}
}
if(flag==true)System.out.println(i);
}
}
}
利用逆拆分法逆向输出输入的数
/*
用户输入任意一个正整数,并将其逆序输出
*/
//逆向拆分实现对任意数的拆分
import java.util.Scanner;
public class WhileReverseTest{
public static void main(String[]args){
Scanner st=new Scanner(System.in);
System.out.println("请输入一个正整数:");
int num=st.nextInt();
//边拆分边打印
//while(num>0){
//System.out.print(num%10);//拆分个位数
//num/=10;//拆分个位数
//}
//将输出储存最后输出
int res=0;
int tem=num;
while(tem>0){
res=res*10+tem%10;
tem/=10;
}
System.out.println(num+"逆序后的结果为:"+res);
}
}
数组
栈用于储存程序运行中声明的所有局部变量
堆用于储存由new关键字创建的数组和对象
在数组的储存中,栈中的数组名实际上是储存堆内存的地址(即数组的首地址)
数组元素的插入
/*
实现数组的插入操作
*/
public class ArrayTest{
public static void main(String[]args){
int []a={1,2,3,0};//数组静态初始化
//在下标为0的位置插入5
for(int i=a.length-1;i>0;i--)
a[i]=a[i-1];
a[0]=5;
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
}
数组元素的删除
/*
实现数组的插入操作
*/
public class ArrayTest{
public static void main(String[]args){
int []a={1,2,3,6};//数组静态初始化
//在下标为0的位置插入5
//将下标为0的元素删除,最后一个位置设置为0
for(int i=0;i<a.length-1;i++)
a[i]=a[i+1];
a[a.length-1]=0;
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
}
数组的优缺点
- 可以通过下标快速访问指定位置的元素
- 要求元素的数据类型相同
- 数组要求内存空间必须连续,并且长度固定就不能更改
- 增减或者删除大量元素时,效率低下
数组的复制
/*
将第一个数组的中间三个元素赋值到第二个数组中
*/
public class ArrayCopyTest{
public static void main(String[]args){
int []array={1,2,3,4,5};
int []brray=new int [3];
// brray[0]=array[1];
//brray[1]=array[2];
//brray[2]=array[3];
//赋值优化之for循环
for(int i=0;i<brray.length;i++)
brray[i]=array[i+1];
for(int i=0;i<brray.length;i++)
System.out.println(brray[i]);
}
}
案例分析
/*
利用数组实现正整数中每个数字出现次数从统计
*/
//利用后拆分法拆分整数
import java.util.Scanner;
public class ArrayCountTest{
public static void main(String[]args){
Scanner st=new Scanner(System.in);
System.out.println("请输入一个整数:");
int num=st.nextInt();
int []tem=new int[10];//建立一个数组储存整数每个数字出现的次数
while(num>0){
tem[num%10]++;//取出该该位数
num/=10;//丢弃该位数
}
for(int i=0;i<10;i++){
if(tem[i]>0)//说明该数出现了
System.out.println(i+"出现了"+tem[i]+"次");
}
}
}
数组工具类
/*
编程实现数组工具类的使用
*/
import java.util.Arrays;//导入该类的包
public class Main{
public static void main(String[]args){
int num[]={2,4,5,4};//静态初始化数组
//java工具类之数组打印
//System.out.println("数组中的元素为:"+Arrays.toString(num));
//由类名直接调用,该方法为静态方法
//java工具类之用任意数填充数组
Arrays.fill(num,0);//将num数组用0填充
for(int i=0;i<num.length;i++)
System.out.println(num[i]);
Arrays.toString(num);
int []a={0,0,0,0,-1};
System.out.println(Arrays.equals(num,a));
}
}
/*
用数组工具类排序和查找
*/
import java.util.Arrays;
public class Arraysort{
public static void main(String args[]){
int a[]={2,3,34,6,7};
Arrays.sort(a);//将数组排序(从小到大)
System.out.println(Arrays.toString(a));
System.out.println(Arrays.binarySearch(a,34));//返回34的数组下标
}
}
二维数组
不齐二维数组
面向对象编程
面向对象指以属性和行为的观点去分析现实中的事务
在面向对象时只分析该对象是否具备该属性和行为
类名当由多个单词构成首字母必须大写
当成员变量由多个单词构成时,第二个单词必须大写,成员方法名也一样
引用变量主要用于记录对象在堆区的内存地址信息,便于下次访问
类的成员变量初始值通常省略不写
可变长参数
/*
编程实现可变长参数的使用
*/
public class ChangeArgument{
//将name参数看成数组,即可以为0-n个参数
//当不确定一个参数传入的数量时使用
public void argument(String... name){
for(int i=0;i<name.length;i++)
System.out.println(name[i]);
}
public static void main(String[]args){
ChangeArgument ar=new ChangeArgument();
ar.argument("hi","hjdhd","jdidi");
}
}
当我们自己写了构造方法,编译器则不提供默认的构造方法
- 构造方法的价值在对象实例化的同时给对象赋值
this关键字
- 若在构造方法中出现this 表示正在构造的对象
2.若在成员方法中出现this 表示正在调用的对象
this关键字本质上为当前类类型的引用
在成员方法中调用成员变量没有写"对象."实际上是隐藏了this.(this为该对象的引用,可以代表当前对象)
3.当函数参数和属性名同名,用this强调区分
4.this 可以作为方法的返回值返回正在调用 的对象(用的不多)
5.在构造方法的第一行可以调用本类中的其他构造方法(了解,开发中用的不多)
对象只声明没有实例化会出现空指针异常
代码的拆分
将main单独写在测试类中
将程序拆分成功能类和测试类,编译测试类的时候,会将功能类一起编译
封装
acwing 特辑
package可以认为写的是代码的文件路径
每一个程序里面只能定义一个public class
procted 表示只能在当前类的子类中访问
对象的多态性:同一个类的不同对象进行同样调用同样的行为,但其表现不同,(子类和父类调用同一个行为时存在)
复习:
编译器优化1:
对于字面量,浮点型的字面量默认为double,整形字面量默认为int ,当int字面量赋给整形小类型时没有出现类型转换报错时是但负的值小于该小类型的范围时候,编译器会优化不会报错,但如果是浮点 的字面量则一定会报错
byte a=5;//int->byte 大类型->小类型 编译器优化不会报错
float c=3.4;//double->float 大类型->小类型 编译器会报错
编译器优化2:
编译器对整形小类型(char short byte)之间的运算,都会将结果转换成int ,主要是防止溢出
计算时将char当成取值范围为0-65536的整形
**虽然char型是以整数存储,但是和int型还是有一定区别的,表现在取值范围上:
char型 占2个字节 无符号 范围是0~65535,所以char c = 65536 就会报错了,专因为越界了**