ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Java零基础入门完整学习路线:从环境搭建到项目实战

Java零基础入门完整学习路线:从环境搭建到项目实战 很多同学在开始学习Java时常常被网上零散的教程搞得晕头转向不知道从哪里入手也不知道学到什么程度才算合格。本文整合了一套完整的Java零基础入门学习路线包含详细的学习笔记、实战案例和避坑指南帮助小白从环境搭建到核心语法再到项目实战一步步掌握Java开发技能。1. Java语言概述与学习价值1.1 Java是什么Java是一种面向对象的编程语言由Sun Microsystems公司于1995年推出。它具有一次编写到处运行的特点这得益于Java虚拟机JVM的存在。Java广泛应用于企业级开发、移动应用开发Android、大数据处理等领域。Java的主要特点包括简单易学语法相对简洁去除了C中复杂的指针概念面向对象支持封装、继承、多态等面向对象特性平台无关性通过JVM实现跨平台运行健壮性强大的异常处理机制和内存管理多线程支持内置对多线程编程的支持1.2 为什么选择Java作为入门语言对于零基础的学习者来说Java是一个很好的起点就业市场需求大Java开发工程师在招聘市场上一直保持较高的需求量生态系统完善有丰富的开源库和框架支持学习资源丰富社区活跃遇到问题容易找到解决方案薪资待遇可观Java开发工程师的平均薪资处于行业前列1.3 Java技术体系组成完整的Java技术体系包括Java SE标准版核心语法和基础类库Java EE企业版企业级应用开发框架Java ME微型版嵌入式设备开发对于初学者建议从Java SE开始学习打好基础后再根据兴趣选择发展方向。2. 学习环境搭建与配置2.1 JDK安装与环境变量配置JDKJava Development Kit是Java开发工具包包含编译、调试、运行Java程序所需的所有工具。Windows系统安装步骤访问Oracle官网下载适合的JDK版本推荐JDK 8或JDK 11运行安装程序记住安装路径如C:\Program Files\Java\jdk1.8.0_291配置环境变量新建系统变量JAVA_HOME值为JDK安装路径在Path变量中添加%JAVA_HOME%\bin验证安装是否成功java -version javac -versionmacOS系统安装# 使用Homebrew安装 brew install openjdk11 # 配置环境变量 echo export PATH/opt/homebrew/opt/openjdk11/bin:$PATH ~/.zshrc source ~/.zshrc2.2 开发工具选择与配置推荐使用IntelliJ IDEA Community版作为初学工具免费使用功能强大智能代码提示和自动补全内置调试工具和版本控制安装完成后进行基础配置设置编码为UTF-8配置代码风格和格式化规则安装必要的插件如Chinese Language Pack2.3 第一个Java程序创建HelloWorld.java文件public class HelloWorld { public static void main(String[] args) { System.out.println(Hello, Java世界!); } }编译和运行javac HelloWorld.java # 编译 java HelloWorld # 运行3. Java基础语法详解3.1 变量与数据类型Java是强类型语言所有变量必须先声明后使用。基本数据类型// 整型 byte age 25; // 1字节-128~127 short year 2024; // 2字节 int score 100; // 4字节最常用 long population 1400000000L; // 8字节后缀加L // 浮点型 float price 19.99f; // 4字节后缀加f double salary 8000.50; // 8字节默认类型 // 字符型 char grade A; // 2字节单引号 // 布尔型 boolean isPassed true; // true或false引用数据类型String字符串类型数组相同类型数据的集合类类型自定义的类3.2 运算符与表达式Java支持丰富的运算符public class OperatorDemo { public static void main(String[] args) { // 算术运算符 int a 10, b 3; System.out.println(a b); // 13 System.out.println(a - b); // 7 System.out.println(a * b); // 30 System.out.println(a / b); // 3整数除法 System.out.println(a % b); // 1取余 // 关系运算符 System.out.println(a b); // true System.out.println(a b); // false // 逻辑运算符 boolean x true, y false; System.out.println(x y); // false System.out.println(x || y); // true System.out.println(!x); // false // 赋值运算符 int c 5; c 3; // 等价于 c c 3 System.out.println(c); // 8 } }3.3 流程控制语句条件语句// if-else语句 int score 85; if (score 90) { System.out.println(优秀); } else if (score 80) { System.out.println(良好); } else if (score 60) { System.out.println(及格); } else { System.out.println(不及格); } // switch语句 char grade B; switch (grade) { case A: System.out.println(优秀); break; case B: System.out.println(良好); break; case C: System.out.println(及格); break; default: System.out.println(不及格); }循环语句// for循环 for (int i 1; i 5; i) { System.out.println(第 i 次循环); } // while循环 int count 1; while (count 5) { System.out.println(while循环第 count 次); count; } // do-while循环 int num 1; do { System.out.println(do-while循环第 num 次); num; } while (num 5);4. 面向对象编程核心概念4.1 类与对象类是对象的模板对象是类的实例。// 定义学生类 public class Student { // 属性成员变量 private String name; private int age; private String studentId; // 构造方法 public Student(String name, int age, String studentId) { this.name name; this.age age; this.studentId studentId; } // 方法成员方法 public void study() { System.out.println(name 正在学习); } public void displayInfo() { System.out.println(姓名 name 年龄 age 学号 studentId); } // getter和setter方法 public String getName() { return name; } public void setName(String name) { this.name name; } } // 测试类 public class TestStudent { public static void main(String[] args) { // 创建对象 Student student1 new Student(张三, 20, 2024001); Student student2 new Student(李四, 22, 2024002); // 调用方法 student1.displayInfo(); student1.study(); student2.displayInfo(); student2.study(); } }4.2 封装、继承与多态封装示例public class BankAccount { private String accountNumber; private double balance; private String owner; public BankAccount(String accountNumber, double balance, String owner) { this.accountNumber accountNumber; this.balance balance; this.owner owner; } // 通过公共方法访问私有属性 public void deposit(double amount) { if (amount 0) { balance amount; System.out.println(存款成功当前余额 balance); } } public void withdraw(double amount) { if (amount 0 amount balance) { balance - amount; System.out.println(取款成功当前余额 balance); } else { System.out.println(取款失败余额不足); } } public double getBalance() { return balance; } }继承示例// 父类 class Animal { protected String name; public Animal(String name) { this.name name; } public void eat() { System.out.println(name 正在吃东西); } public void sleep() { System.out.println(name 正在睡觉); } } // 子类 class Dog extends Animal { private String breed; public Dog(String name, String breed) { super(name); // 调用父类构造方法 this.breed breed; } public void bark() { System.out.println(name breed 在汪汪叫); } // 方法重写 Override public void eat() { System.out.println(name 正在吃狗粮); } } // 测试类 public class InheritanceDemo { public static void main(String[] args) { Dog dog new Dog(旺财, 金毛); dog.eat(); // 调用重写后的方法 dog.sleep(); // 调用继承的方法 dog.bark(); // 调用子类特有方法 } }4.3 接口与抽象类接口示例// 定义接口 interface Flyable { void fly(); // 抽象方法 int MAX_SPEED 1000; // 常量 } interface Swimmable { void swim(); } // 实现多个接口 class Duck implements Flyable, Swimmable { private String name; public Duck(String name) { this.name name; } Override public void fly() { System.out.println(name 在天空中飞翔); } Override public void swim() { System.out.println(name 在水面上游泳); } }5. 集合框架与常用类库5.1 List集合import java.util.ArrayList; import java.util.List; public class ListDemo { public static void main(String[] args) { // 创建ArrayList ListString fruits new ArrayList(); // 添加元素 fruits.add(苹果); fruits.add(香蕉); fruits.add(橙子); fruits.add(葡萄); // 遍历集合 System.out.println(所有水果); for (String fruit : fruits) { System.out.println(fruit); } // 根据索引访问 System.out.println(第一个水果 fruits.get(0)); // 修改元素 fruits.set(1, 芒果); System.out.println(修改后的第二个水果 fruits.get(1)); // 删除元素 fruits.remove(2); System.out.println(删除后集合大小 fruits.size()); } }5.2 Map集合import java.util.HashMap; import java.util.Map; public class MapDemo { public static void main(String[] args) { // 创建HashMap MapString, Integer studentScores new HashMap(); // 添加键值对 studentScores.put(张三, 85); studentScores.put(李四, 92); studentScores.put(王五, 78); // 遍历Map for (Map.EntryString, Integer entry : studentScores.entrySet()) { System.out.println(entry.getKey() 的成绩是 entry.getValue()); } // 根据键获取值 int score studentScores.get(李四); System.out.println(李四的成绩 score); // 检查键是否存在 if (studentScores.containsKey(赵六)) { System.out.println(赵六的成绩存在); } else { System.out.println(赵六的成绩不存在); } } }5.3 String字符串操作public class StringDemo { public static void main(String[] args) { String str1 Hello; String str2 Java; // 字符串连接 String result str1 str2; System.out.println(result); // Hello Java // 字符串长度 System.out.println(字符串长度 result.length()); // 字符串比较 System.out.println(是否相等 str1.equals(hello)); // false System.out.println(忽略大小写比较 str1.equalsIgnoreCase(hello)); // true // 字符串截取 String sub result.substring(6, 10); System.out.println(截取结果 sub); // Java // 字符串分割 String text apple,banana,orange,grape; String[] fruits text.split(,); for (String fruit : fruits) { System.out.println(fruit); } // 去除空格 String withSpaces Hello World ; System.out.println(去除空格 withSpaces.trim()); } }6. 异常处理机制6.1 异常分类与处理Java异常分为检查异常和非检查异常。public class ExceptionDemo { public static void main(String[] args) { // try-catch处理异常 try { int[] numbers {1, 2, 3}; System.out.println(numbers[5]); // 数组越界 } catch (ArrayIndexOutOfBoundsException e) { System.out.println(数组索引越界 e.getMessage()); } catch (Exception e) { System.out.println(发生其他异常 e.getMessage()); } finally { System.out.println(无论是否发生异常都会执行finally块); } // 抛出异常 try { checkAge(15); } catch (IllegalArgumentException e) { System.out.println(年龄检查异常 e.getMessage()); } } // 方法声明抛出异常 public static void checkAge(int age) throws IllegalArgumentException { if (age 18) { throw new IllegalArgumentException(年龄必须大于等于18岁); } System.out.println(年龄验证通过); } }6.2 自定义异常// 自定义异常类 class InsufficientBalanceException extends Exception { private double currentBalance; private double amountRequired; public InsufficientBalanceException(double currentBalance, double amountRequired) { super(余额不足当前余额 currentBalance 需要金额 amountRequired); this.currentBalance currentBalance; this.amountRequired amountRequired; } public double getCurrentBalance() { return currentBalance; } public double getAmountRequired() { return amountRequired; } } // 使用自定义异常 class BankAccount { private double balance; public BankAccount(double balance) { this.balance balance; } public void withdraw(double amount) throws InsufficientBalanceException { if (amount balance) { throw new InsufficientBalanceException(balance, amount); } balance - amount; System.out.println(取款成功剩余余额 balance); } }7. 输入输出流操作7.1 文件读写操作import java.io.*; import java.util.Scanner; public class FileIODemo { public static void main(String[] args) { // 写入文件 try (FileWriter writer new FileWriter(test.txt)) { writer.write(Hello Java!\n); writer.write(这是文件写入测试\n); writer.write(第三行内容); System.out.println(文件写入成功# 1. 两数之和 ## 题目 给定一个整数数组 nums 和一个目标值 target请你在该数组中找出和为目标值的那 两个 整数并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是你不能重复利用这个数组中同样的元素。 示例: text 给定 nums [2, 7, 11, 15], target 9 因为 nums[0] nums[1] 2 7 9 所以返回 [0, 1]解题思路暴力法遍历每个元素 x并查找是否存在一个值与 target - x 相等的目标元素。class Solution { public int[] twoSum(int[] nums, int target) { for (int i 0; i nums.length; i) { for (int j i 1; j nums.length; j) { if (nums[j] target - nums[i]) { return new int[] { i, j }; } } } throw new IllegalArgumentException(No two sum solution); } }复杂度分析时间复杂度O(n^2) 对于每个元素我们试图通过遍历数组的其余部分来寻找它所对应的目标元素这将耗费 O(n) 的时间。因此时间复杂度为 O(n^2)。空间复杂度O(1)。两遍哈希表为了对运行时间复杂度进行优化我们需要一种更有效的方法来检查数组中是否存在目标元素。如果存在我们需要找出它的索引。保持数组中的每个元素与其索引相互对应的最好方法是什么哈希表。通过以空间换取速度的方式我们可以将查找时间从 O(n) 降低到 O(1)。哈希表正是为此目的而构建的它支持以 近似 恒定的时间进行快速查找。我用“近似”来描述是因为一旦出现冲突查找用时可能会退化到 O(n)。但只要你仔细地挑选哈希函数在哈希表中进行查找的用时应当被摊销为 O(1)。一个简单的实现使用了两次迭代。在第一次迭代中我们将每个元素的值和它的索引添加到表中。然后在第二次迭代中我们将检查每个元素所对应的目标元素target - nums[i]是否存在于表中。注意该目标元素不能是 nums[i] 本身class Solution { public int[] twoSum(int[] nums, int target) { MapInteger, Integer map new HashMap(); for (int i 0; i nums.length; i) { map.put(nums[i], i); } for (int i 0; i nums.length; i) { int complement target - nums[i]; if (map.containsKey(complement) map.get(complement) ! i) { return new int[] { i, map.get(complement) }; } } throw new IllegalArgumentException(No two sum solution); } }复杂度分析时间复杂度O(n) 我们把包含有 n 个元素的列表遍历两次。由于哈希表将查找时间缩短到 O(1) 所以时间复杂度为 O(n)。空间复杂度O(n) 所需的额外空间取决于哈希表中存储的元素数量该表中存储了 n 个元素。一遍哈希表事实证明我们可以一次完成。在进行迭代并将元素插入到表中的同时我们还会回过头来检查表中是否已经存在当前元素所对应的目标元素。如果它存在那我们已经找到了对应解并立即将其返回。class Solution { public int[] twoSum(int[] nums, int target) { MapInteger, Integer map new HashMap(); for (int i 0; i nums.length; i) { int complement target - nums[i]; if (map.containsKey(complement)) { return new int[] { map.get(complement), i }; } map.put(nums[i], i); } throw new IllegalArgumentException(No two sum solution); } }复杂度分析时间复杂度O(n) 我们只遍历了包含有 n 个元素的列表一次。在表中进行的每次查找只花费 O(1) 的时间。空间复杂度O(n) 所需的额外空间取决于哈希表中存储的元素数量该表最多需要存储 n 个元素。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进