Day1学习
JDK11
-
长期支持版(LTS)
-
安装过程要注意路径为全英文,防止后续编译运行时产生报错
-
设置系统的环境变量,新建%JAVA_HOME%指向JDK的根目录,然后在Path变量中添加%JAVA_HOME%\bin
-
设置完成后,打开cmd输入java --version和javac --version,如果控制台输出版本信息,证明环境配置成功
Maven生命周期
Maven的生命周期就是为了对所有的maven项目构建过程进行抽象和统一。
-
clean:清理工作。
-
default:核心工作,如:编译,测试,打包,安装,部署。
-
site:生成报告,发布站点。
每套生命周期包含一些阶段(phase),阶段是有顺序的,后面的阶段依赖于前面的阶段。
Maven生命周期阶段
-
clean:移除上一次构建生成的文件
-
compile:编译项目源代码
-
test:使用合适的单元测试框架运行测试(junit)
-
package:将编译后的文件打包,如jar,war等。
-
install:安装项目到本地仓库。
执行指定的生命周期的两种方式:
-
在idea中,右侧的maven工具栏,双击运行。
-
在当前项目中打开命令提示行,使用mvn命令运行(如mvn compile)。
依赖管理
依赖配置
依赖:指当前项目运行所需要的jar包,一个项目中可以引入多个依赖。
注意事项
-
如果引入的依赖在本地仓库不存在,将会链接远程仓库或者中央仓库,然后下载依赖
-
如果不知道依赖的坐标信息,可以到https://mvnrepository.com/中搜索。
依赖传递
-
依赖具有传递性
-
直接依赖:在当前项目中通过依赖配置建立的依赖关系
-
间接依赖:被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源。
-
排除依赖(exclusion):排除依赖指主动断开依赖的资源,被排除的资源无需指定版本
依赖范围
依赖的jar包,默认情况下,可以在任何地方使用,可以通过使用设置其作用范围。
作用范围:
-
主程序范围有效(main文件夹范围内)
-
测试程序范围有效(test文件夹范围内)
-
是否参与打包运行(package指令范围内)
企业项目目录结构
-
src/main/java:存放核心业务代码
-
src/main/resources:存放配置文件,如application.properties
-
src/test/java:专门用于编写单元测试
HashSet集合的底层原理
- 基于哈希表存储数据的
哈希值
-
哈希值指得是一个int类型的随机值,Java中每个对象都有一个所谓的哈希值
-
Java中所有对象都可以调用Object类提供的hashCode方法来返回该对象的哈希值
对象哈希值的特点
-
同一个对象多次调用hashCode方法返回的哈希值是相同的
-
不同的对象,哈希值大概率是不同的,有一定可能相同(哈希碰撞)
哈希表
-
JDK8之前,哈希表=数组+链表
-
创建一个默认长度为16的数组,默认加载因子0.75,数组名table
-
使用元素的哈希值对数组的长度做运算计算出存入的位置(类似于取余)
-
判断当前位置是否为null,如果是null直接存入
-
如果当前位置不为null,表示有元素,调用equals方法比较:相等则不存,不相等则存入数组
-
JDK8之前,新元素存入数组,占老元素位置,老元素挂下面
-
JDK8之后,新元素直接挂在老元素下面
-
-
哈希表中的元素如果存储超过默认长度与加载因子的乘积时,就会进行扩容,扩容成原来的两倍
-
JDK8开始,当链表长度超过8,数组长度>=64时,自动将链表转换成红黑树,提高检索性能
-
-
JDK8之后,哈希表=数组+链表+红黑树
-
红黑树,就是可以自平衡的二叉树
Maven依赖下载报错
在首次拉取依赖时,IDEA控制台爆出了大量的红色报错。经排查是因为网络波动导致部分jar包下载不完整,本地仓库中留下了.lastUpdated后缀的失败标记文件。解决方案是删除本地仓库中所有带.lastUpdated后缀的文件,然后在IDEA中点击"Reload All Maven Projects"重新触发下载,配合阿里云镜像,最终所有依赖顺利解析。
变量数据类型
java
package com.arguan.variable;
public class VariableDemo {
public static void main(String[] args) {
// 目标:认识变量
print();
}
public static void print() {
// 定义变量
int a;
// 赋值
a = 10;
// 输出
System.out.println(a);
// 定义一个小数变量,存储一个学生的Java成绩
double score = 90.5;
System.out.println(score);
// 为什么要用变量记住数据?
// 提高处理数据的灵活性和维护性
// 变量的特点:变量里的数据是可以被替换的
int age = 18;
age = 19;
System.out.println(age);
age = age + 1;
System.out.println(age);
System.out.println("==================");
// 需求:微信钱包目前有9.9,发出去了5元,又收到了6元,请实时输出钱包金额
double money = 9.9;
System.out.println(money);
money = money - 5 + 6;
System.out.println(money);
System.out.println("==================");
char ch = 'A'; // 65
System.out.println(ch + 1);
char ch2 = 'a';
System.out.println(ch2 + 1);
System.out.println("===================");
// 程序中可以直接写进制数据
int i1 = 0B01100001;// 二进制 必须以0b开头
System.out.println(i1);
int i2 = 0141;// 八进制 必须以0开头
System.out.println(i2);
int i3 = 0xFA;// 十六进制 必须以0x开头
System.out.println(i3);
}
}
分支循环
if
java
package com.arguan.branch;
public class IfDemo1 {
public static void main(String[] args) {
// 目标:认识if语句,搞清楚其写法和应用场景
demo1();
}
public static void demo1() {
int age = 18;
if (age >= 18) {
System.out.println("可以投票");
}
System.out.println("程序结束");
// 注意:if语句中如果只有一行代码,大括号可以省略不写
}
public static void demo2() {
int age = 17;
if (age >= 18) {
System.out.println("可以投票");
} else {
System.out.println("不可以投票");
}
System.out.println("程序结束");
}
public static void demo3() {
int age = 17;
if (age >= 18) {
System.out.println("可以投票");
} else if (age >= 16) {
System.out.println("可以参与问卷调查");
} else {
System.out.println("不可以投票");
}
System.out.println("程序结束");
}
}
switch
java
package com.arguan.branch;
import java.util.Scanner;
public class SwitchDemo3 {
public static void main(String[] args) {
// 目标:搞清楚switch分支结构的应用和写法,理解其执行流程
demo1();
}
// 需求:根据男女性别的不同推荐不同的书本信息给其观看
public static void demo1() {
// 1 让用户输入自己的性别
System.out.println("请输入您的性别:");
Scanner sc = new Scanner(System.in);
String sex = sc.next();
// 2 根据用户输入的性别这个值,判断该做什么
switch (sex) {
case "男":
System.out.println("推荐《java从入门到精通》");
break;
case "女":
System.out.println("推荐《java从入门到精通》");
break;
default:
System.out.println("你不是人,没有东西推荐!");
}
}
}
for
java
package com.arguan.loop;
public class ForDemo1 {
public static void main(String[] args) {
// 目标:掌握for循环的书写,搞清楚其执行流程
}
public static void test() {
// 需求:使用for循环,打印三行Hello World
for (int i = 0; i < 3; i++) {
System.out.println("Hello World!");
}
}
}
while
java
package com.arguan.loop;
public class WhileDemo5 {
public static void main(String[] args) {
// 目标:认识while循环的写法,理解清楚其执行顺序
test1();
}
public static void test1() {
int i = 1;
while (i <= 5) {
System.out.println("hello world");
i++;
}
}
}
doWhile
java
package com.arguan.loop;
public class DoWhileDemo8 {
public static void main(String[] args) {
// 目标:理解do...while循环及特点
}
// 使用do-while循环控制打印输出三行HelloWorld
public static void test() {
// 特点:先执行后判断(至少执行一次)
int i = 0;
do {
System.out.println("HelloWorld");
i++;
} while (i < 3);
}
}
数组
静态初始化
java
package com.arguan;
public class ArrayDemo1 {
public static void main(String[] args) {
// 目标:认识使用数组的好处,数组的定义,访问
getStudentName();
}
public static void getStudentName(){
// 1 定义一个数组,保存15个学生姓名
// 静态初始化数组,定义数组的时候,数据已经确定好了
String[] names = {"小王","小李","小张","小赵","小钱","小孙","小李","小王","小王","小王","小王","小王","小王","小王"};
// 2 随机获取一个索引值
int index = (int)(Math.random()*names.length);
// 3 根据索引值,获取数组中的关系
String name = names[index];
System.out.println(name);
}
}
动态初始化
java
package com.arguan;
import java.util.Scanner;
public class ArrayDemo2 {
public static void main(String[] args) {
// 目标:掌握数组的另一种定义方式,动态初始化数组
inputScore();
}
public static void inputScore(){
// 1 你需要一个数组来存储8名学生的成绩
// 动态初始化数组,只确定数组的类型和存储数据的容量,不事先存入具体的数据
// 数组类型[] 数组名 = new 数组类型[数组的长度];
double[] scores = new double[8];
// scores = [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
// 0 1 2 3 4 5 6 7
// 2 录入8名学生的成绩,存入到数组中去
Scanner sc = new Scanner(System.in);
for (int i = 0; i < scores.length; i++) {
System.out.println("请输入第" + (i + 1) + "位学生的成绩:");
scores[i] = sc.nextDouble();
}
// 3 遍历数组,统计总分,最高分,最低分,平均分
double sum = scores[0];
double max = scores[0];
double min = scores[0];
for (int i = 1; i < scores.length; i++) {
double score = scores[i];
// 4 累加当前遍历到的成绩
sum += score;
// 5 判断当前遍历到的成绩,是不是最高分
if (score > max) {
max = score;
}
// 6 判断当前遍历到的成绩,是不是最低分
if (score < min) {
min = score;
}
}
System.out.println("总分:" + sum);
System.out.println("平均分:" + sum / scores.length);
System.out.println("最高分:" + max);
System.out.println("最低分:" + min);
}
}
集合
List
java
package com.arguan.list;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListDemo1 {
public static void main(String[] args) {
// 目标:掌握list独有的功能
List<String> names = new ArrayList<>();
// 添加数据
names.add("张三");
names.add("李四");
names.add("王五");
names.add("赵六");
System.out.println(names);
// 给第三个位置插入一个数据:赵敏
names.add(2, "赵敏");
System.out.println(names);
// 删除李四
System.out.println(names.remove(1));
System.out.println(names);
// 把王五修改成金毛
System.out.println(names.set(2, "金毛"));
System.out.println(names);
// 根据索引获取数据
System.out.println(names.get(0));
System.out.println("----------------------");
// 1 for循环
for (int i = 0; i < names.size(); i++) {
System.out.println(names.get(i));
}
// 2 迭代器
Iterator<String> it = names.iterator();
while (it.hasNext()) {
String name = it.next();
System.out.println(name);
}
// 3 增强for
for (String name : names) {
System.out.println(name);
}
// 4 lambda表达式
names.forEach(System.out::println );
}
}
Set
java
package com.arguan.hashset;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
public class SetDemo1 {
public static void main(String[] args) {
// 目标:认识Set集合
// 1 创建一个Set集合
// Set<String> set = new HashSet<>();特点:无序,不重复,无索引
Set<String> set = new LinkedHashSet<>();// 有序,不重复,无索引
set.add("hello");
set.add("world");
set.add("java");
set.add("java");
System.out.println(set);
// 2 创建一个TreeSet集合 排序默认升序排序,不重复,无索引
Set<Double> set2 = new TreeSet<>();
set2.add(3.14);
set2.add(1.23);
set2.add(5.67);
System.out.println(set2);
System.out.println("========================");
String s1 = "acd";
String s2 = "abc";
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s2.hashCode());
}
}
Map
java
package com.arguan.map;
import java.util.*;
public class MapDemo2 {
public static void main(String[] args) {
// 目标:掌握Map集合的常用方法
Map<String,Integer> map = new HashMap<>();
map.put("张三",18);
map.put("李四",20);
map.put("王五",22);
System.out.println(map);
// 写一些代码演示常用方法
System.out.println(map.get("张三"));// 根据键取值
System.out.println(map.containsKey("张三"));// 判断是否包含某个键
System.out.println(map.containsValue(18));// 判断是否包含某个值
System.out.println(map.size());// 获取集合大小
System.out.println(map.isEmpty());// 判断集合是否为空
System.out.println(map.remove("张三"));// 删除元素
// map.clear();// 清空集合
System.out.println(map);
System.out.println(map.keySet());// 获取所有的键
System.out.println(map.values());// 获取所有的值
System.out.println(map.entrySet());// 获取所有的键值对对象
// 获取所有的键放到一个Set集合中
Set<String> keySet = map.keySet();
for (String key : keySet) {
System.out.println(key);
}
// 获取所有的值放到一个Collection集合中
Collection<Integer> values = map.values();
for (Integer value : values) {
System.out.println(value);
}
}
}
字符串
java
package com.arguan.StringDemo;
import java.util.Scanner;
public class StringDemo1 {
public static void main(String[] args) {
// 目标:掌握字符串的创建方式,调用String提供的方法处理字符串
// 1 直接使用""创建字符串对象
String s1 = "hello world";
System.out.println(s1);
System.out.println(s1.length());// 处理字符串的方法
// 2 通过构造器初始化对象
String s2 = new String();// 创建空字符串对象
System.out.println(s2);
String s3 = new String("hello world");
System.out.println(s3);
char[] chars = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'};
String s4 = new String(chars);
System.out.println(s4);
byte[] bytes = {104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100};
String s5 = new String(bytes);
System.out.println(s5);
System.out.println("--------------------------");
// 只有""给出的对象存放在字符串常量池 而且相同数据只存放一份
String t1 = "abc";
String t2 = "abc";
System.out.println(t1 == t2);
String t3 = new String("abc");
String t4 = new String("abc");
System.out.println(t3 == t4);
// 调用字符串的方法,封装字符串的数据
// 简易版的登录
String loginName = "admin";
System.out.println("请输入用户名:");
Scanner sc = new Scanner(System.in);
String inputName = sc.next();
// 字符串对象的内容比较,不可以使用==,==默认比较地址,字符串对象内容一样地址不一定一样
// 判断字符串内容,建议使用equals。只关心内容一不一样,不关心地址
if (loginName.equals(inputName)) {
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
}
}
异常处理
java
package com.arguan.exception;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo4 {
public static void main(String[] args) {
// 目标:掌握异常的处理方案1 底层异常都抛出去给最外层调用者
System.out.println("程序开始执行...");
try {
show();
System.out.println("底层程序执行成功");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("程序结束");
}
public static void show() throws Exception {
System.out.println("show2方法开始执行...");
// 编译一场,编译阶段报错,编译不通过
String str = "2024-07-09 11:12:13";
// 把字符串时间解析成Java中的一个日期对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse(str);// ParseException 提醒程序员代码可能出现问题
System.out.println(date);
InputStream is = new FileInputStream("D:/meinv.png");
System.out.println("show2方法执行完毕...");
}
}
java
package com.arguan.exception;
import java.util.Scanner;
public class ExceptionDemo5 {
public static void main(String[] args) {
// 目标:掌握异常处理方案2 捕获异常并尝试重新修复
// 接收用户的一个定价
double price = 0;
while (true) {
try {
price = userInputPrice();
break;
} catch (Exception e) {
System.out.println("输入的定价有误,请重新输入");
}
}
System.out.println("用户输入的定价是:" + price);
}
public static double userInputPrice() {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个定价");
double price = sc.nextDouble();
return price;
}
}
Maven基本命令
| 命令 | 核心作用 | 适用场景 |
|---|---|---|
mvn clean |
清理:删除项目根目录下的 target 目录。 |
重新构建前清理旧产物,避免缓存干扰;编译报错时清理缓存。 |
mvn compile |
编译:编译 src/main/java 下的主程序代码。 |
快速检查代码是否有语法错误,生成 .class 文件到 target/classes。 |
mvn test |
测试:编译并运行 src/test/java 下的单元测试。 |
验证业务逻辑,生成测试报告存于 target/surefire-reports。 |
mvn package |
打包:执行 clean → compile → test → 打包。 |
项目开发完成后,在 target 目录生成 .jar (普通项目) 或 .war (Web项目) 包。 |
mvn install |
安装:打包后,将 jar 包安装到本地仓库 (~/.m2/repository)。 |
多模块项目必备。当 A 模块需要依赖 B 模块时,必须先对 B 执行 install,A 才能找到 B。 |
mvn deploy |
部署:将包上传到远程私服 (如 Nexus)。 | 团队协作时,将公共组件上传到公司私服,供其他同事下载依赖。 |