文章目录
第一章 Java基础知识
一、Java的技术体系
1、JavaSE标准版:后面两个版本的基础,也就是学习后面两个版本必须先学习JavaSE。
2、JavaEE企业版:为企业级应用开发提供的一套解决方案。
3、JavaME小型版:为开发移动设备的应用提供了一套解决方案,目前已被淘汰。
二、JDK的组成
JDK是Java语言的软件开发工具包,由JRE(包含JVM和核心类库)和开发工具组成。
- JVM(Java Virtual Machine):Java虚拟机,真正运行Java程序的地方。
- 核心类库:Java本身写好的一些程序,给程序员调用的。
- JRE(Java Runtime Enviroment):Java的运行环境
- 开发工具:编译工具javac.exe和运行工具java.exe,还有一些其他的反编译工具、文档工具等。
三、Java开发程序的三步骤
编译:javac HelloWorld.java
运行:java HelloWorld
注意事项:首字母大写,源代码文件后缀名为.java,文件名称必须与代码的类名称一致。
四、配置环境变量
安装JDK时,配置path和JAVA_HOME环境变量。
(1)path环境变量:Path环境变量用于记住系统程序的路径,方便程序员在命令行窗口的任意目录下启动程序。
(2)JAVA_HOME环境变量:告诉操作系统JDK的位置。
五、命令行窗口的常用命令
六、IDEA编写Java程序
(1)首先得在IDEA中创建一个Project(工程、也叫项目)。
(2)需要在Project中创建Module(模块),一个工程中可以包含多个模块。
(3)需要在Module中新建Package(包),一个模块中可以有多个包。
(4)需要在Package中新建Class(类),一个包中可以包含多个类。
七、IDEA常用快捷键
八、字符集的编码、解码操作
1、编码
2、解码
第二章 Java基础语法
一、注释
1、注释的作用:注释是解释说明程序的问题,方便自己和别人阅读代码。
2、注释种类
(1)单行注释
//一行注释内容
(2)多行注释
/*
这里写注释文字
可以写多行
*/
(3)文档注释
/**
这里写文档注释
也可以写多行,文档注释可以利用JDK的工具生成帮助文档
*/
3、注释快捷键
二、字面量
1、作用:告诉程序员数据在程序中的书写格式。
2、常用字面量
3、特殊字符:\n代表换行,\t代表的是Tab
4、Java程序中支持书写二进制、八进制、十六进制的数据,分别需要以0B或者0b、0、0X或者0x开头。
5、计算机表示数据的最小组成单元是:字节,1B = 8b
三、变量
1、作用:变量是用来记录程序中的数据的。其本质上是内存中的一块区域。
2、定义格式
数据类型 变量名称 = 数据;
3、示例
//小数字面量默认为double,如果希望小数是float,后面加上F/f
float f = 3.14F;
long lg =4345436546L;
四、常量
1、定义:被static final修饰的成员变量,称之为常量。
public static final String SCHOOL_NAME = "传智教育";
2、作用:通常用于记录系统的配置信息。
3、常量命名规范:建议都采用大写字母命名,多个单词之前有_隔开
五、关键字
1、定义:关键字是java语言中有特殊含义的单词。比如用int表示整数,用double表示小数。
2、常用关键字
3、案例-获取用户键盘输入的数据
(1)步骤
①在class类上导包
②得到一个用于键盘扫描器对象Scanner
③开始调用sc的功能,来接收用户键盘输入的数据。
(2)代码
import java.util.Scanner;
public class Test{
public static void main{
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的年龄");
int age = sc.nextInt();
System.out.println("我的年龄是:"+age);
//sc这个东西还有键盘录入字符串的功能,这个功能的名字叫next
System.out.println("请输入你的姓名");
String name = sc.next();
System.out.println("我的姓名是:"+name);
}
}
4、案例-random随机数
(1)步骤
①在class类上导包
②得到一个随机数对象
③开始调用随机数的功能获取0-9之间的随机数
(2)代码
import java.util.Random;
public class Test{
public static void main{
Random r = new Random(); // 创建一个Random对象,用于生成随机数。
// 调用Random提供的功能:nextInt得到随机数。
for (int i = 1; i <= 20; i++) {
int data1 = r.nextInt(10); // 0 - 9
int data2 = r.nextInt(10) + 5; // 5 - 14
System.out.println(data1);
}
}
}
5.1 final关键字
1、定义:final关键字是最终的意思,可以修饰类、修饰方法、修饰变量。
2、具体情况
(1)final修饰类:该类称为最终类,特点是不能被继承
(2)final修饰方法:该方法称之为最终方法,特点是不能被重写。
(3)final修饰变量:该变量只能被赋值一次。
5.2 this关键字
(1)定义:this就是一个变量,用在方法中,可以拿到当前对象。
(2)应用场景:用来解决变量名称冲突问题。
public class Student {
double score;
public void printThis(){
System.out.println(this); //把自己对象的地址传给this接收
}
public void printPass(double score){
if(this.score > score){ //this.score是指当前对象的成员变量
System.out.println("恭喜你分数更高");
}
}
}
(3)示例
public class Student {
public void printThis(){
System.out.println(this); //把自己对象的地址传给this接收
}
}
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(s1); //com.itheima.branch.Student@4eec7777
s1.printThis(); //com.itheima.branch.Student@4eec7777
Student s2 = new Student(); //s1和s2地址不同,指向不同的学生对象
System.out.println(s2); //com.itheima.branch.Student@3b07d329
s2.printThis(); //com.itheima.branch.Student@3b07d329
}
六、标识符
1、定义:标志符其实就是名字。像类名,变量名其实都是标志符。
2、命名要求
(1)标识符由是字母、数字、下划线、$组成。
(2)不能以数字开头,不能是Java的关键字,区分大小写。
3、建议规范
(1)变量名称:满足标识符命名要求,建议全英文、有一样,首字母小写,满足“驼峰模式”。
(2)类名称:满足标识符命名要求,建议全英文、有一样,首字母大写,满足“驼峰模式”。
七、数据类型
1、基础数据类型:4大类8种
2、引用数据类型:string
String代表的是字符串类型,定义的变量可以用来记住字符串。
八、类型转换
1、自动类型转换:数据范围小的变量可以直接赋值给数据范围大的变量。
(1)示例
byte a = 12;
int b = a; //这里就发生了自动类型转换(把byte类型转换int类型),不会报错
(2)自动类型转换顺序如下图所示
2、表达式的自动类型转换
(1)运算规则:多种数据类型参与运算,最终结果以表达式的最高类型为准。byte,short,char 三种类型数据在和其他类型数据运算时,都会转换为int类型再运算。
(2)示例
byte a = 10;
int b = 20;
long c = 30;
byte d = 40;
long rs = a + b + c; //表达式的最高类型是long
int e = a + d; //byte是转换为int再参与运算的
3、强制类型转换:强行将范围大的数据,赋值给范围小的变量。
(1)格式
数据类型 变量2 = (数据类型)变量1; //Alt+Enter
(2)规则:强制类型转换可能造成数据溢出。浮点型强转为整型,丢掉小数部分,保留整数部分返回。
(3)示例
int i = 1500;
byte j = (byte)i;
System.out.println(j); //-36 强制类型转换可能造成数据溢出
九、运算符
1、算术运算符
“+”符号除了用于加法运算,还可以作为连接符。“+”符号与字符串运算的时候是用作连接符的,其结果依然是一个字符串。
2、自增自减运算符
(1)自增自减只能对变量进行操作,不能操作字面量。
(2)示例
int i = 10;
int rs = ++i; // 先加后用
System.out.println(rs); //11
System.out.println(i); //11
int j = 10;
int rs2 = j++; // 先用后加
System.out.println(rs2); //10
System.out.println(j); //11
3、赋值运算符
(1)基本赋值运算符:“=”
(2)扩展赋值运算符
4、关系运算符
5、逻辑运算符:把多个条件放在一起运算,最终返回布尔类型的值:true、false
6、三元运算符
格式:首先计算关系表达式的值,如果关系表达式的值为true,则返回值1;如果关系表达式的值为false, 则返回值2。
条件表达式 ? 值1 : 值2;
十、集合
1、定义:集合是一个容器,用来装数据的,类似于数组。
2、与数组的区别:数组一旦创建大小不变,而集合大小可变。
3、集合的体系结构
3.1 Collection集合体系
3.1.1 Collection集合
(1)定义:Collection代表单列集合,是单列集合的祖宗,它规定的方法是全部单列集合都会继承的。单列集合是指每个元素(数据)只包含一个值。
(2)Collection集合特点
-
List系列集合: 添加的元素是有序、可重复、有索引。
① ArrayList、LinekdList: 有序、可重复、有索引。(有序是指输入顺序和输出顺序一致) -
Set系列集合:添加的元素是无序、不重复、无索引
① HashSet: 无序、不重复、无索引;
② LinkedHashSet: 有序、不重复、无索引。
③ TreeSet:按照大小默认升序排序、不重复、无索引。
(3)迭代器
public static void main(String[] args) {
Collection<String> c = new ArrayList<>(); //多态写法,new一个实现类类来定义父类接口
c.add("赵敏");
c.add("小昭");
c.add("素素");
c.add("灭绝");
System.out.println(c); //[赵敏, 小昭, 素素, 灭绝]
//先获取迭代器对象
Iterator<String> it = c.iterator();
//用于判断当前位置是否有元素可以获取
while(it.hasNext()){
//获取当前位置的元素,然后自动指向下一个元素.
String e = it.next();
System.out.println(s);
}
}
(4)forEach遍历集合
c.forEach(s->{
System.out.println(s);
});
(5)集合的井发修改异常:使用迭代器遍历集合时,又同时在删除集合中的数据,程序就会出现并发修改异常的错误。同时增强for循环遍历集合就是迭代器遍历集合的简化写法,使用增强for循环遍历集合,又在同时删除集合中的数据时,程序也会出现并发修改异常的错误。
List<String> list = new ArrayList<>();
list.add("王麻子");
list.add("小李子");
list.add("李爱花");
list.add("张全蛋");
list.add("晓李");
System.out.println(list); // [王麻子, 小李子, 李爱花, 张全蛋, 晓李]
//需求:找出集合中带"李"字的姓名,并从集合中删除
Iterator<String> it = list.iterator();
while(it.hasNext()){
String name = it.next();
if(name.contains("李")){
//list.remove(name); 井发修改异常
it.remove(name); //删除达代器当前遍历到的数据,每删除一个数据后,相当于也在底层做了i--
}
}
System.out.println(list);
3.1.2 List集合
(1)List集合的特有方法
(2)遍历方式
① for循环(因为list循环有索引)
② 迭代器
③ 增强for循环
④ Lambda表达式
(3)ArrayList集合
① 底层原理
a.ArrayList基于数组实现的,利用无参构造器创建的集合,会在底层创建一个默认长度为0的数组.
b.添加第一个元素时,底层会创建一个新的长度为10的数组,存满时,会扩容1.5倍
c.如果一次添加多个元素,1.5倍还放不下,则新创建数组的长度以实际为准
② 应用场景:根据索引查询数据比如根据随机索引取数据 或者数据量不是很大时。
③ 特点
a.查询速度快(根据索引查询数据快): 查询数据通过地址值和索引定位,查询任意数据耗时相同。
b.删除效率低:可能需要把后面很多的数据进行前移
c.添加效率极低:可能需要把后面很多的数据后移,再添加元素,或者也可能需要进行数组的扩容
(4)LinkedList集合
① 底层原理:基于双链表实现的
特点:查询慢,无论查询哪个数据都要从头开始找。链表增删相对快。
特点:查询慢,增删相对较快,但对首尾元素进行增删改查的速度是极快的。
② 方法
③ 应用场景:希望记住元素的添加顺序,且增删首尾数据的情况较多。
a.设计队列:先进先出,后进后出
//创建一个队列:先进先出、后进后出
LinkedList<String> queue = new LinkedList<>();
//入对列
queue.addLast("第1号人");
queue.addLast("第2号人");
queue.addLast("第3号人");
System.out.println(queue);
//出队列
System.out.println(queue.removeFirst()); //第1号人
System.out.println(queue.removeFirst()); //第2号人
System.out.println(queue.removeFirst()); //第3号人
b.设计栈:后进先出,先进后出
//创建一个栈对象
LinkedList<String> stack = new ArrayList<>();
//压栈(push) 等价于 addFirst()
stack.push("第1颗子弹");
stack.push("第2颗子弹");
stack.push("第3颗子弹");
System.out.println(stack); //[第3颗子弹, 第2颗子弹,第1颗子弹]
//弹栈(pop) 等价于 removeFirst()
System.out.println(statck.pop()); //第3颗子弹
System.out.println(statck.pop()); //第2颗子弹
System.out.println(statck.pop()); //第1颗子弹
3.1.3 Set集合
(1)HashSet集合
① HashSet的底层原理:基于哈希表 = 数组 + 链表 + 红黑树
哈希值是一个int类型的数值,Java中每个对象都有一个哈希值。
//对象可以调用Obejct类提供的hashCode方法,返回该对象自己的哈希值
public int hashCode(): 返回对象的哈希码值
//同一个对象多次调用hashCode()方法返回的哈希值是相同的
//不同的对象,它们的哈希值一般不相同,但也有可能会相同(哈希碰撞)。
② 使用场景:不在意元素顺序,也没有重复元素需要存储,只希望增删改查都快
(2)LinkedHashSet集合
① 底层原理:基于哈希表 = 数组 + 链表 + 红黑树,但它的每个元素都额外的多了一个双链表的机制记录它前后元素的位置。
② 使用场景:希望记住元素的添加顺序,也没有重复元素需要存储,且希望增删改查都快。
(3)TreeSet集合
① 底层原理:基于红黑树实现
② 使用场景:要对元素进行排序,也没有重复元素需要存储?且希望增删改查都快。
3.1.4 Collections:是操作集合的工具类。
(1)常用方法
可变参数
定义:一种特殊形参,定义在方法、构造器的形参列表里,常常用来灵活的接收数据。
格式
数据类型...参数名称
可变参数的特点和好处
特点:可以不传数据给它;可以传一个或者同时传多个数据给它;也可以传一个数组给它
3.2 Map集合体系
3.2.1 Map集合
(1)定义:Map集合称为双列集合,格式:{keyl=value1,key2=value2,key3=value3},一次需要存一对数据做为一个元素,每个元素“key=value”称为一个键值对/键值对对象/一个Entry对象,Map集合也被叫做“键值对集合”。
Map<String Integer> map = new map<>();
(2)特点:Map集合的所有键是不允许重复的,但值可以重复,键和值是一一对应的,每一个键只能找到自己对应的值。
(3)常用方法
(4)遍历方式
① 键找值:先获取Map集合全部的键,再通过遍历键来找值。
public class MapTest1 {
public static void main(String[] args) {
Map<String, Double> map = new HashMap<>();
map.put("蜘蛛精", 162.5);
map.put("蜘蛛精", 169.8);
map.put("紫霞", 165.8);
map.put("至尊宝", 169.5);
System.out.println(map);// map = {蜘蛛精=169.8, 至尊宝=169.5, 紫霞=165.8}
// 1、获取Map集合的全部键
Set<String> keys = map.keySet();
// 2、遍历全部的键,根据键获取其对应的值
for (String key : keys) {
double value = map.get(key); // 根据键获取对应的值
System.out.println(key + "=====>" + value);
}
}
}
② 键值对:把“键值对“看成一个整体进行遍历。
public class MapTest2 {
public static void main(String[] args) {
Map<String, Double> map = new HashMap<>();
map.put("蜘蛛精", 169.8);
map.put("紫霞", 165.8);
map.put("至尊宝", 169.5);
// 调用Map集合提供entrySet方法,把Map集合转换成键值对类型的Set集合
Set<Map.Entry<String, Double>> entries = map.entrySet();
for (Map.Entry<String, Double> entry : entries) {
String key = entry.getKey(); //获取键
double value = entry.getValue(); //获取值
System.out.println(key + "---->" + value);
}
}
}
③ Lambda
public class MapTest3 {
public static void main(String[] args) {
Map<String, Double> map = new HashMap<>();
map.put("蜘蛛精", 169.8);
map.put("紫霞", 165.8);
map.put("至尊宝", 169.5);
System.out.println(map);
/*遍历map集合,BiConsumer是接口,不能new对象,所以要用匿名内部类
map.forEach(new BiConsumer<String, Double>() {
@Override
public void accept(String k, Double v) {
System.out.println(k + "---->" + v);
}
});
*/
//遍历map集合,传递Lambda表达式
map.forEach(( k, v) -> {
System.out.println(k + "---->" + v);
});
}
}
3.2.2 HashMap
(1)底层原理:HashMap跟HashSet的底层原理是一模一样的,都是基于哈希表 = 数组 + 链表 + 红黑树实现的。
(2)特点:无序,不重复,无索引
3.2.3 LinkedHashMap
(1)底层原理:底层数据结构依然是基于哈希表实现的,只是每个键值对元素又额外的多了一个双链表的机制记录元素顺序(保证有序)。
(2)特点:有序,不重复,无索引
3.2.4 TreeMap
(1)底层原理:TreeMap跟TreeSet集合的底层原理是一样的,都是基于红黑树实现的排序。
(2)特点:不重复、无索引、可排序(按照键的大小默认升序排序,只能对键排序)
4、集合的嵌套
(1)定义:集合中的元素是一个集合
(2)示例
记录如下省份和其对应的城市信息,记录成功后,要求可以查询出湖北省的城市信息
江苏省 =南京市,扬州市,苏州市,无锡市,常州市
湖北省 =武汉市,孝感市,十堰市,宜昌市,鄂州市
河北省 =石家庄市,唐山市,邢台市,保定市,张家口市
public class Test {
public static void main(String[] args) {
// 定义一个Map集合存储全部的省份信息,和其对应的城市信息。
Map<String, List<String>> map = new HashMap<>();
// 定义一个List集合存储全部的城市信息
List<String> cities1 = new ArrayList<>();
Collections.addAll(cities1, "南京市","扬州市","苏州市" ,"无锡市","常州市");
map.put("江苏省", cities1);
List<String> cities2 = new ArrayList<>();
Collections.addAll(cities2, "武汉市","孝感市","十堰市","宜昌市","鄂州市");
map.put("湖北省", cities2);
List<String> cities3 = new ArrayList<>();
Collections.addAll(cities3, "石家庄市","唐山市", "邢台市", "保定市", "张家口市");
map.put("河北省", cities3);
System.out.println(map);
//查询湖北省的城市信息
List<String> cities = map.get("湖北省");
for (String city : cities) {
System.out.println(city);
}
//查询所有信息
map.forEach((p, c) -> {
System.out.println(p + "----->" + c);
});
}
}