Java基础
一、Java入门
Java是由SUM公司开发的计算机语言,它是面向对象的程序设计语言。
Java包括三大体系:J2SE、J2EE、J2ME,分别用于c/s模式开发、Web开发、嵌入式开发。其中,J2EE不仅是企业级软件开发标准,更是一种规范。
1 Java简介
1.1 Java常用指令
(1)javac--------java编译器:将源代码(.java)编译成字节码文件(.class);
(2)java---------java解释器:字节码文件经过JVM解释器解释成二进制机器码被计算机识别;
(3)javadoc----java文档生成器。
1.2 Java的特点与特性
(1)主要特点:面向对象、跨平台、开源、安全、多线程。
(2)主要特性:封装、多态、继承、抽象。
1.3 Java开发工具包
Java开发工具包JDK和JRE是开发、调试、编译、运行Java的整套工具。
- JDK(开发人员)开发环境
- JRE(运维人员)运行环境
1.4 Java重要机制JVM、垃圾回收器
(1)JVM
定义:是运用硬件、软件手段实现的虚拟计算机,内部有完善的硬件结构,如:处理器、堆栈、寄存器,还有相应的指令系统。(不同操作系统JDK不同,有对应的JVM)
(2)垃圾回收器
特点:Java提供了一个系统级的线程对内存中的数据进行清理。(即使有垃圾处理器仍可能出现内存溢出)
数据清理标准:①为对象赋予空值后不再调用;②为对象赋予新值,即重新分配了内存空间;
1.5 注释
(1)单行注释://
(2)多行注释:/* /
(3)文档注释:/* */
二、Java数据类型、变量和运算符
Java语言的基本组成部分,如数据类型、变量、表达式、运算符等等。
1 数据类型
- 基本数据类型(又称原始数据类型,代表未经处理的最原始数据)
(1)整数型:byte(字节型)、short(短整型)、int(整型)、long(长整型);
(2)浮点型:float(浮点型)、double(双精度型);
(3)char(字符型)、boolean(布尔型); - 引用数据类型
String(多个字符、字母、汉字、数字)、数组、类、包装类、集合、接口等等。
2 变量
- 标识符(对象名):首字符为字母、_、$。
对象名要有一定的描述意义
- 声明变量:数据类型 变量名;
对象命名规则:
①小驼峰:除第一个单词外,其他单词首字母都大写;
②大驼峰:单词首字母都大写;(比如:类名、函数名、属性名、命名空间)
- 初始化变量(赋值)
未初始化的变量直接使用会报错
3 运算符
运算符 | 分类 | 说明 |
---|---|---|
一元运算符 | ++、- -、! | |
二元运算符 | 算数运算符 | 先 (*、/、%),后 (+、-) |
关系运算符 | 先( >、>=、<、<=),后( ==、!=) | |
逻辑运算符 | 先(&&),后(双竖线) | |
赋值运算符 | 先(*=、/=、%=),后(+=、-=、=) | |
三元运算符 | 表达式?值1:值2; |
int a = 10;
boolean b = a % 2 == 0? true:false;
关系运算符和逻辑运算符的结果为布尔值
“==”可用于判断引用地址是否相等
4 数据类型转换
4.1 自动类型转换(小→大)
整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。
转换条件:①类型兼容;②目标类型取值>源类型;
规律:
1、小类型自动转化为大类型;
2、整数类型可以自动转化为浮点类型,可能会产生舍入误差;
Float和Double提供了快速的运算,然而问题在于转换为二进制的时候,有些数字不能完全转换,只能无限接近于原本的值
3、字符可以自动提升为整数;
//1.隐式类型转换
int i = 128;
double b = i;//128.0
//2.整数类型可以自动转化为浮点类型,可能会产生舍入误差
float floatValue1=2+10f;
float floatValue2=floatValue1-11.9f;
System.out.println(floatValue2);//0.10000038
//3.字符可以自动提升为整数
char Value1 ='a';
int Value2=Value1+10;
System.out.println(Value2);//107
4.2 强制类型转换(大→小)
语法:目标类型 变量 = (目标类型)值;
强制类型转换,在要强制类型转换的前面加上括号,然后在括号里面加上你要转换的类型
注意点:
- 强制类型转换可能导致溢出或损失精度;
- 在把容量大的类型转换为容量小的类型时必须使用强制类型转换;
- 浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入;
- 不能对布尔值进行转换;
- 不能把对象类型转换为不相干的类型;
//1.数据溢出(数据类型超过了计算机字长的界限而出现的数据溢出)
int i = 128;
byte b = (byte)i;//-128 内存溢出
//byte 最大值是 127,这里给了它128,所以它超出了最大值
//2.字符强制转换成数字
char c1 = 'a';
char c2 = '中';
System.out.println(c1);//a
System.out.println((int)c1);//97 强制转换
System.out.println(c2);//中
System.out.println((int)c2);//20013 强制转换
所有的字符本质还是数字(参考ASCLL编码表)
三、流程控制语句
1 流程控制语句
- 顺序结构:自上而下、从左到右;
- 条件结构:根据条件判断结果,决定程序的执行方向;
- 循环结构:在给定条件成立时,仅反复执行某程序段,知道条件不成立为止;
2 条件(选择)语句
2.1 if语句
if(条件){
//语句块
}
注意:
①语句块中只有一行代码时,{ }可省略;
② 对布尔型变量进行判断,不要用“==”号;
③ 对Srtring类型进行判断,用equals实现;
2.2 if-else语句
if(条件){
//语句块1
}else{
//语句块2
}
if(条件){
//语句块1
}if else(条件){
//语句块2
}else{
//语句块3
}
注意:if-else内部嵌套可以无穷次嵌套,但是三次以上会导致程序变慢。
2.3 switch-case语句
switch(常量表达式){
case 数值:
语句;
break;
case 数值:
语句;
break;
case 数值:
语句;
break;
……
default:
语句;//上述条件都不满足时执行
}
switch后的常量表达式支持byte、short、int、char类型(jdk1.7后支持String类型、jdk1.5后支持enum(枚举))
switch-case条件语句存在的意义?
答:if-else在解决多分支问题时不直观,层次较多时容易出错,此时采用switch-case较为合适;
3 循环语句
3.1 while循环
while(条件){
//语句块
}
3.2 do-while循环
do{
//语句块
}while(条件)
3.3 for循环
for(表达式1;条件;表达式2){
//语句块
}
执行顺序:表达式1→条件→循环体→表达式2
表达式1和表达式2可以省略,但建议保留
①while和for循环的区别?
答:不确定循环次数时用while,知道循环次数时用for。
②while和do-while循环的区别?
答:while循环先判断条件再决定循不循环,do-while是先执行一遍再判断条件。所以,相同条件下,do-while比while多循环一次。
4 break和continue
- break:立即结束整个循环,执行循环后面的语句
- continue:跳过本次循环,continue后的语句不执行,进入下一次循环
四、数组
数组用于存储相同数据类型的多个元素。
1 一维数组
1. 1 一维数组的声明、定义、初始化
- 声明
类型 []数组名;
类型 数组名[];
//例子
int []x;
int x[];
数组名命名规则参见变量名命名规则
2. 定义
类型 []数组名 = new 类型[长度];
类型 数组名[] = new 类型[长度];
//例子
int []x = new int[10];
int x[] = new int[10];
长度可以为0;长度一旦创建不可改变;长度可以是一个常量表达式;
- 默认初始化
数值型默认0
布尔型默认false
String类型默认NULL
- 显式初始化
//例子
int x[] = new int[]{...};
int x[] = {...}
1.2 数组的遍历和长度
- 遍历
通过for循环遍历
//例子
for(int index=0;index<10;index++){
item[index] = index * 3;
}
- 长度
长度指数组中元素的个数,数组长度:数组名.lenght
数组下标从0开始,比如长度为10,下标为0~9.
1.3 数组的应用
- 冒泡排序
//1.静态化创建数组
int[] arr = {18,13,50,15,4,17,18};
//2.创建中间变量
int temp = 0;
//3.排序(从小到大)
for(int i = 0 ;i< arr.length -1; i++){
for(int j = 0; j<arr.length-1-i; j++){
if(arr[j]>arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
- 选择排序
2 二维数组
常用于保险单、税单、乘法表、区域人口表等等。
2.1 二维数组的声明、定义、初始化
- 声明
数据类型 [][]数组名;
数据类型 数组名[][];
//例子
int[][] x;
int x[][];
- 定义
数据类型 [][]数组名 = new 数据类型[][];
数据类型 数组名[][] = new 数据类型[][];
//例子
int [][]x;
x = new int[2][3];
int [][]x = new int[2][3];//两行三列
- 显式初始化
int [][]x = new int[][]{
{...},{...},{...},...};
int [][]x = {
{...},{...},{...},...};
//例子
int[][] array = {
{1,2,3},{4,5,6},{7,8,9}};
- 遍历
实质是一维数组嵌套循环。
int[][] array = {
{1,2,3},{4,5,6},{7,8,9}};
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3 ; j++) ;
System.out.println(array[i][j]);
}
}
2.2 不规则数组
不规则数组就可以让每一列的大小不同,从而节约数组的储存空间,提高我们的储存空间利用率。
public class IrregularArray {
public static void main(String[] args) {
int[][] arr = new int[3][];//只定义行数为3
arr[0] = new int[]{1, 2};
arr[1] = new int[]{3, 4, 5};
arr[2] = new int[]{6, 7, 8, 9};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
//输出结果
1 2
3 4 5
6 7 8 9
应用场景:
①存储数据长度不同的数组。
②存储数据结构中的树状结构。
③存储图像中的像素矩阵。
④存储游戏中的地图数据。
五、类与对象(一)
1 类与对象、方法
特征=属性=变量
行为=方法
实例化=创建对象=声明对象=new
类是对象的抽象(属性、行为),对象是类的具体实例。
1.1 类
类必须包含一个或以上的构造方法
定义:具有相同属性和共同行为的一组对象的集合。
分类:①系统类;②自定义类;
语法:
[访问修饰符] class 类名{ //访问修饰符:public(公共)、private(私有)、protected(同一包中的父子类)、默认(包修饰)
类属性声明;
类方法声明;
}
1.2 对象
具有明确属性和行为的对象是客观存在的实体。
类与对象的区别?
①类是对一类对象的描述,是创建一个对象的“模版”,是对象的抽象。
②对象表示现实世界中某个具体的事物,是类的一个实例。
1.3 方法
定义:完成特定功能的代码块。
组成:访问修饰符、返回值类型、方法名、参数列表、方法体。
语法:
[访问修饰符] 返回值类型 方法名(参数列表){
//方法体
}
返回值类型:①无返回值void;②有返回值方法体至少包含一个return;
方法名命名参照小驼峰
分类:静态方法、实例方法、构造方法、抽象方法。
//实例方法
//1.创建实例化对象
类 对象名 = new 类();
//2.访问方法,有参数的列出参数
对象名.方法名(参数列表);
//3.访问属性
对象名.变量名;
2 对象的操作
- 实例化对象
只有实例化对象后才能真正使用。
类 对象名 = new 类(); - 访问属性
实例化对象访问变量改变自己的状态。
//实例化Student类对象
Student student = new Student();
student.name = "张三";
student.sex = "男";
student.age = 17;
- 调用方法
对象名.方法名();
注意:
①调用有参的方法,参数个数必须一致,且参数类型必须一致或能自动转换;
②调用无返回值的方法时,不能得到任何类型的值;
③同一个类中,方法能互相调用;
④方法的递归调用;
void sort(){
...
sort();
...
}
3 构造方法
分类:①默认(不带参)构造方法;②带参构造方法;
作用:初始化成员变量;
语法:
[访问修饰符] 类名([参数列表]){
//方法体
}
//例子
public class people {
private String name;
private int age;
//无参构造
public people() {
}
//有参构造方法
public people(String name, int age) {
this.name = name;
this.age = age;
}
}
特点:
①方法名必须与类名相同,不能有返回值且不含void;
②不能显式调用,而是在实例化对象时自动调用;
③只要在类中显示定义了构造方法,默认的构造方法则失效;
④同一个类中可以有多个构造方法,但多个构造方法之间必须参数个数或类型不同;
⑤构造方法可以形成重载;
⑥在创建一个类的新对象时,系统自动调用该类的构造方法为新对象初始化;
⑦java类必须包含一个或一个以上的构造方法;
4 重载
特征:
①在一个类中;
②方法名相同;
③参数列表不同;(参数个数、类型、顺序)
④与返回类型和访问修饰符无关;
5 补充
- 2字节=1字符;1字节=8位;
- char用’ ';
- 默认浮点小数为double,float要加f;
- 数值型的数组默认值为0;double类型默认值为false;
- 一个表达式计算完后,结果的类型取决于表达式中的最高类型(自动升级),例如:12*12.9f+23.9 的结果为double类型;
六、类与对象(二)
1 静态变量、静态方法、静态代码块
关键字:static
静态成员:包括静态变量、静态方法、静态代码块。静态成员归整个类所有,不依赖于类特定的实例,被类中所有实例共享。可以在对象创建前访问,只要类被系统加载就能根据类名在全局数据区内找到。
静态成员 | 说明 | |
---|---|---|
静态变量 | 语法 | static 数据类型 变量名; |
访问静态变量 | ①类名.静态变量名; ②(创建实例对象访问:类 对象名 = new 类;)对象名.静态变量名; | |
静态方法 | 语法 | static [访问修饰符] 返回值类型 方法名(参数列表) { //方法体;} |
访问静态方法 | ①类名.静态方法名;②(创建对象访问)对象名.静态方法名(参数列表); | |
静态代码块 | 语法 | static{ //方法体;} |
注意:
①静态变量属于某个类,被所有实例共享,既可以通过类名访问又可以通过实例名访问。
②静态变量值只初始化一次。
③静态代码块只在静态方法执行前被执行一次,在java虚拟机加载类时执行。
④静态方法不能用this和super关键字。因为这两个关键字和特定实例相关。
静态变量和实例变量的区别?
①静态变量在内存中只有一个内存空间,加载类时完成静态变量的内存分配;
②实例变量中每创建一个实例,就会为实例变量分配一次内存,各个对象访问自己的变量;
③静态方法不能访问非静态实例变量和方法,但实例方法可以访问静态变量和方法;
初始化顺序:静态变量初始化→静态代码块→初始化静态方法→实例变量初始化→代码块→构造方法
变量类型?
①类变量:static修饰(项目);
②实例变量-全局变量:(类);
③方法变量-局部变量:(方法);
2 final常量
final关键字修饰的变量为常量。
语法:final 变量类型 变量名 = 值;常设置为静态常量 static final ...
特征:
①可修饰静态变量、实例变量、局部变量,均表示常量;
②final类型的变量必须显式初始化;
③final变量只能被赋值一次;
④final变量定义时一般大写字母命名,多个单词用”_“隔开;
3 final对象
用final修饰对象,则该对象变量始终只能引用一个对象,但可以改变对象的内容。
4 包
若一个类访问了来自另一个包的类,需通过import先将该类引用到当前类。
七、常用包
1 java.lang包
该包提供了常用字符串类(String类、StringBuffer类)、包装类(Boolean、Character、Long、Float、Double)、数学函数类Math。
1.1 字符串类
String类
不变长度的字符串。
- 创建字符串
String str1;
str1 = "hello";
String str2 = "hello";
String str3 = new String("hello");
- String类的常用方法
方法 | 说明 |
---|---|
lenght() * | 返回字符串长度。字符串为值空返回0,字符串为null,表示未分配内存空间,无法计算长度 |
concat() | concat()连接字符串或用”+“连接字符串。例:字符串1.concat(字符串2); |
valueOf() * | 将目标类型转化成字符串型。 |
subString() | 返回截取后的字符串,下标从0开始。与JavaScript中的subStr()类似。例:subString(1,4);//从下标为1截取到下标为4 subString(1);//从下标为1截取到最后 |
compareTo() | 比较两个字符串的大小。字符串1.compare(字符串2); |
equals() * | 判断两个字符串是否相等(equals()比较的是值,”==“比较的是地址) |
format(String format,Object…args) * | 使用指定格式字符串和参数返回一个格式化字符串 |
indexOf(int ch) * | 返回指定字符在字符串中第一次出现的位置索引 |
trim() * | 清除字符串两端的空格 |
//valueOf()和concat()结合连接字符串
int a = 100;
int b = 2;
String s1 = String.valueOf(a).concat(String.valueOf(b));
String s2 = String.valueOf(a) + String.valueOf(b);
StringBuffer类
可变长度的字符串,默认长度16。只能通过new使用。
- 创建StringBuffer对象(构造方法)
StringBuffer();//创建空的可变字符串,起始容量16个字符长度
StringBuffer(int index);//以起始长度为index创建一个空的可变字符串
StringBuffer(String str);//创建可变字符串,初始化为str
- StringBuffer类常用方法
方法 | 说明 |
---|---|
append() * | 将指定字符追加到字符串后面。字符串1.append(字符串2); |
insert() * | 在指定位置插入字符串。例:字符串1.insert(2,“123”);//在索引为2的位置插入字符串”123“ |
void setcharA(int pos,char ch) | 设置指定索引上的字符 |
void deletecharA(int pos,char ch) | 删除指定索引上的字符 |
void rplace(int start,int end,String str) | 替换指定索引间的字符串 |
1.2 包装类
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int * | Integer |
long | Long |
float | Float |
double | Double |
char * | Character |
boolean | Boolean |
Integer num1 = new Integer(10);
Integer num2 = Integer.valueOf("10") ;
Integer num3 = Integer.valueOf("10",10);//10指十进制
1.3 Math类
java.lang.Math
都是静态的,包含指数、对数、平方根、三角运算等等。含两个静态常量:E和PI。Math类为final类型,无子类。
- Math类常用静态方法
静态方法 | 说明 |
---|---|
abs() | 返回绝对值 |
max() | 返回两个参数的较大值 |
min() | 返回两个参数的较小值 |
random() * | 返回[0.0,1.0)之间的double类型随机数 |
round() | 返回四舍五入的整数 |
sin() | 正弦 |
exp() | 返回自然对数的幂 |
sqrt() | 平方根 |
pow() | 幂运算 |
2 java.util包
2.1 Date类
获取系统时间/设置日期时间。
Date date = new Date();
System.out.print(date);//得到系统时间
2.2 SimpleDateFormat类
格式化和解析日期的具体类(java.text.SimpleDateFormat)。
Date date = new Date();
String format = "yyyy年MM月dd日 HH时mm分ss秒";//日期格式(HH表示24小时制,hh表示12小时制)
SimpleDateFormat sdf = new SimpleDateFormat(format);
String str = sdf.format(date);//data→String
Date d = sdf.parse(Str);//String→date
2.3 Calender类
灵活的设置/得到时间。
- 调用getTime()方法获取当前时间
Calender rightNow = Calender.getInstance();
System.out.print(rightNow.getTime());//得到系统时间
- 使用add()修改时间
①获取当前日期;
②用add()修改当前日期;
③在add(int field,int amount)方法中,第一个参数是要修改的部分,第二个参数是如何修改;
④用get()方法获取时间的特定部分;
Calender rightNow = Calender.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(”yyyy-mm-dd“);//格式化
String today = sdf.format(rightNow,getTime());//获取当前日期
rightNow.add(Calender,DATE,-1);
String yesterday = sdf.format(rightNow,getTime());
DATE常量:一个月中某一天;
DAY_OF_WEEK常量:一周中周几;
**补充:实体类构成、单例模式
1 实体类的构成
2 单例模式
3.debug
2分钟教会你如何Java中DeBug【IDEA中Java】
在eclipse中如何使用Debug进行调试
- 双击左侧打断点(取消断点同样双击)
- 右上角进入debug界面(常用)
选择所需断点位置(勾选右侧需要测试的断点位置)
- 启动debug(右键选择Debug As 启动/直接在上方启动)
选择需要debug的文件
成功启动debug
- 操作debug
第一个表示跳下一个断点(快捷键F8)
第二个表示进入调用的方法中(快捷键F5)
第三个表示跳下一行(快捷键F6)
八、继承
1 关键字
2 特征
3 this和super关键字
4 final关键字
九、多态
1 多态
2 抽象类
3 接口
十、集合 *
1 集合概述
1.1 概述
- 当数组种存储的数据不断增加,用数组形式存储数据不太方便,并且数组中的元素不能删除,无法反映员工辞职或解雇等实际情况。所以,java提供了集合框架,所有的集合类和集合接口都在java.util包下。
- 集合框架可以解决复杂的数据存储问题。
- 集合就是在内存中申请一块空间用来存储数据,是替换定长数组的一种引用数据类型。
- Java集合大致可以分为三种体系,分别是List、Set、Map。其中,List代表有序、可重复的集合;Set代表无序、不可重复的集合;Map代表具有映射关系的集合,以键值对形式存在,无序、键不可重复。
1.2 集合与数组的区别
- 长度
数组长度一旦定义就不可更改(优点:控制内存空间,有效提高查询速度);
集合长度由内容决定; - 内容
数组可以储存基本数据类型和引用数据类型;
集合中只能存储引用数据类型,存储的是对象的内存地址; - 元素
数组中只能存储同一种类型;
集合可以存储不同类型数据(一般情况下也只存一种) - 集合结构
在java中每一个不同的集合,底层会对应不同的数据结构。往不同的集合中存储元素,等于将数据放到了不同的数据结构当中。
2 Collection接口(Iterator迭代器)
Collection集合的方法
常用方法 | 说明 |
---|---|
add(obj)、add(index,obj) | 在集合末尾添加元素、在指定索引处添加元素 |
addAll(list) | 将一个集合的所有元素加到另一个集合后面 |
size() | 返回集合中元素的个数 |
get(index) | 获取指定索引处的对象 |
set(index,obj) | 修改指定索引处的对象 |
clear() | 清空本类集合 |
indexOf(obj) | 返回obj对象第一次出现的位置索引值 |
2.1 Iterator迭代器
Java.util.Iterator接口是对于Collection集合惊醒迭代的迭代器。
常用方法 | 说明 |
---|---|
hasNext() | 如果被迭代的集合位遍历完毕,返回true |
next() | 返回集合中的下一个元素 |
remove() | 删除集合中上一次next方法返回的元素 |
例:循环获取集合元素
// 引入 ArrayList 和 Iterator 类
import java.util.ArrayList;
import java.util.Iterator;
public class RunoobT