25.Java语法知识总结

  1. 25.总结
    1. 25.1 核心要点速览
      1. 开发环境搭建
      2. 注释
      3. 变量类型
        1. 整型
        2. 浮点型
        3. 其他类型
      4. 常量
      5. 类型转换
      6. 运算符
      7. 流程控制
        1. 条件分支
        2. 循环
      8. 数组
        1. 一维数组
        2. 二维数组与交错数组
      9. Arrays类常用方法
      10. 函数
        1. 基本语法
        2. 与C#的区别
      11. 面向对象-封装
        1. 类声明
        2. Java中没有的C#特性
      12. 面向对象-继承
        1. Object类关键方法
      13. 面向对象-多态
        1. 方法重写
        2. 接口
      14. 内部类
        1. 普通内部类
        2. 匿名内部类
      15. 字符串-String
        1. 声明方式
        2. 字符串比较
        3. 常用方法
      16. 字符串-StringBuilder
      17. 泛型
        1. 与C#的区别
        2. 类型通配符
      18. 集合类-List
        1. ArrayList与LinkedList
        2. 常用方法
      19. 集合类-Set
        1. HashSet与TreeSet
        2. TreeSet独有方法
      20. 集合类-Map
        1. HashMap与TreeMap
        2. 常用方法
      21. 异常处理
        1. 基本语法
        2. 方法抛出异常
        3. 自定义异常
      22. Lambda表达式
        1. 语法
        2. 函数式接口
      23. 方法引用
      24. Function接口
      25. 常用类库
        1. 包装类
        2. 大数据类
        3. Math类
        4. Random类
    2. 25.2 面试题精选
      1. 基础题
        1. 1. Java变量类型及选择
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        2. 2. String比较方式
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
      2. 进阶题
        1. 1. ArrayList与LinkedList的区别
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        2. 2. HashMap与TreeMap的区别
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        3. 3. Java多态与C#的区别
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
      3. 深度题
        1. 1. HashSet与TreeSet的底层实现及选择
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        2. 2. Lambda表达式与函数式接口
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章

25.总结


25.1 核心要点速览

开发环境搭建

步骤 说明
安装JDK 建议使用JDK 8(Android/Unity生态常见要求)
配置环境变量 JAVA_HOME、Path、CLASSPATH
安装IDE IDEA(JetBrains)或Eclipse

注释

三种注释:单行 //、多行 /* ... */、文档 /** ... */(用于类/方法说明)。

变量类型

整型

类型 字节 位数 取值范围
byte 1 8 -128 ~ 127
short 2 16 -32768 ~ 32767
int 4 32 -21亿多 ~ 21亿多
long 8 64 -9百万兆 ~ 9百万兆

注意:Java没有无符号类型(Java 8新增部分无符号方法,使用较少)。

浮点型

类型 字节 位数 说明
float 4 32 需加f后缀,如 1.5f
double 8 64 默认小数类型

其他类型

类型 字节 说明
boolean 4(单个)/ 1(数组) 默认值false
char 2 单字符,单引号'A'
String 不定 引用类型,首字母大写

常量

关键字 final,声明时必须初始化,不可修改。

static final int MAX_VALUE = 100;

类型转换

方式 说明 示例
隐式转换 小范围→大范围,自动转换 byte → short → int → long → float → double
显式转换 括号强转,可能丢失精度 int i = (int)2.5f;
字符串转数值 包装类parse方法 Integer.parseInt("101", 2);

运算符

分类 运算符 说明
算术 + - * / % 整数相除只保留整数
自增减 ++ -- i++先用后加,++i先加后用
比较 > < >= <= == != 结果为boolean
逻辑 && || ! &&||有短路特性
位运算 & | ^ ~ << >> >>> >>>为无符号右移
三目 条件 ? 值1 : 值2 简化if-else

流程控制

条件分支

语句 特点
if-else 支持多分支判断
switch 支持整型、字符型、字符串、枚举;贯穿时可插入代码逻辑

循环

语句 特点
while 先判断后执行
do-while 先执行后判断,至少执行一次
for 固定次数循环
foreach for(元素类型 x : 遍历对象),用于遍历数组/集合

循环控制break跳出循环,continue跳过本次。

数组

一维数组

int[] arr = new int[5];
int[] arr2 = {1, 2, 3, 4};
int arr3[] = new int[]{1, 2, 3};

二维数组与交错数组

Java中二维数组和交错数组写法相同,都是 [][]

int[][] arr2D = new int[3][2];
int[][] jagged = new int[3][];
jagged[0] = new int[]{1, 2, 3};

Arrays类常用方法

方法 作用
fill(数组, 值) 填充数组
fill(数组, 起, 止, 值) 填充指定范围
sort(数组) 升序排序
copyOf(数组, 长度) 复制数组
copyOfRange(数组, 起, 止) 复制指定范围
binarySearch(数组, 元素) 二分查找(需先排序)

函数

基本语法

修饰符 返回类型 函数名(参数类型 参数名, ...)
{
    return 返回值;
}

与C#的区别

特性 Java C#
ref/out
可变参数 类型... 参数名 params 类型[]
默认参数
命名规范 驼峰命名法 帕斯卡命名法

面向对象-封装

类声明

class 类名
{
    成员变量;
    成员方法;
    构造函数;
    finalize();  // 类似析构函数
}

Java中没有的C#特性

  • 成员属性(get/set)
  • 析构函数(有finalize替代)
  • 索引器
  • 运算符重载

面向对象-继承

特性 Java C#
继承关键字 extends :
父类调用 super base
类型判断 instanceof is
密封关键字 final sealed

Object类关键方法

  • getClass():获取类型,类似C#的getType()
  • toString():转字符串
  • equals():比较内容(==比较引用地址)

面向对象-多态

方法重写

Java方法默认可重写(除非声明为final),@Override注解可选但推荐使用。

@Override
public void Eat() {
    super.Eat();  // 调用父类方法
}

接口

特性 Java C#
继承接口关键字 implements :
接口字段 只能是static final常量 不允许
显式实现接口 不存在

概念 说明
package 类似C#命名空间,解决类名冲突
import 引入包,类似C#的using
import static 静态导入,直接使用静态成员

包名规则:统一小写,用.分割,如 com.公司名.项目名.模块名

内部类

普通内部类

外部类 outer = new 外部类();
外部类.内部类 inner = outer.new 内部类();
  • 内部类可直接访问外部类所有成员(包括私有)
  • 同名成员通过this外部类.this区分

匿名内部类

new 抽象类/接口() {
    @Override
    public void 方法() { }
};

字符串-String

声明方式

方式 说明
直接赋值 相同字符串指向同一引用
new String() 相同字符串也是不同引用

字符串比较

  • ==:比较引用地址
  • equals():比较内容
  • equalsIgnoreCase():忽略大小写比较

常用方法

方法 作用
length() 长度
indexOf()/lastIndexOf() 正向/反向查找
charAt(int i) 获取指定位置字符
substring(起, 止) 截取子串
trim() 去首尾空格
replace(旧, 新) 替换
split(分隔符) 分割
toUpperCase()/toLowerCase() 大小写转换

字符串-StringBuilder

用于频繁修改字符串的场景,效率远高于String拼接。

方法 作用
append(内容) 追加
insert(位置, 内容) 插入
delete(起, 止) 删除
toString() 转String

泛型

与C#的区别

特性 Java C#
泛型方法声明 public <T> void Method(T t) public void Method<T>(T t)
泛型约束 <T extends 类/接口> where T : 类/接口
类型通配符 ?
基础类型 必须用包装类 可直接使用

类型通配符

类名<?> obj = null;
obj = new 类名<子类>();

集合类-List

ArrayList与LinkedList

特性 ArrayList LinkedList
底层结构 数组 链表
访问效率
插入删除效率

常用方法

方法 作用
add(元素) 添加
remove(索引/元素) 删除
get(索引) 获取
set(索引, 元素) 修改
contains(元素) 判断是否存在
size() 元素个数
clear() 清空

集合类-Set

HashSet与TreeSet

特性 HashSet TreeSet
底层结构 哈希表
排序 无序 自动排序
效率 较低

共同特点:不允许重复元素,不能通过索引访问。

TreeSet独有方法

方法 作用
first()/last() 获取首/尾元素
pollFirst()/pollLast() 取出并移除首/尾
headSet(元素) 获取元素之前的集合
tailSet(元素) 获取元素之后的集合

集合类-Map

HashMap与TreeMap

特性 HashMap TreeMap
底层结构 哈希表
null键/值 允许 键不允许null
排序 无序 自动排序
效率 较低

常用方法

方法 作用
put(键, 值) 添加键值对
get(键) 获取值
remove(键) 删除
containsKey(键) 判断键是否存在
containsValue(值) 判断值是否存在
keySet() 获取所有键
values() 获取所有值

异常处理

基本语法

try {
    // 可能出错的代码
} catch (异常类型 ex) {
    // 处理异常
} finally {
    // 无论如何都执行
}

方法抛出异常

public void Test() throws 异常类型1, 异常类型2 {
    // 方法体
}

自定义异常

继承Exception,通过throw抛出。

Lambda表达式

语法

(参数) -> { 代码块 }
参数 -> 结果表达式

函数式接口

仅包含一个抽象方法的接口,用于装载Lambda表达式。

interface ITest {
    int Test();
}
ITest t = () -> { return 1 + 2; };

注意:Lambda内不能修改局部变量,可修改外部类成员变量。

方法引用

类型 语法 示例
静态方法 类名::静态方法名 类名::Test
成员方法 对象名::成员方法名 obj::Test
构造函数 类名::new 类名::new
数组构造 类型[]::new Integer[]::new

Function接口

java.util.function.Function<T, R>:T为参数类型,R为返回值类型。

Function<Integer, String> f = (a) -> a.toString();
String result = f.apply(100);

常用类库

包装类

说明
Integer/Long/Double 数值包装类,提供parse、toString等方法
Boolean 布尔包装类
Character 字符包装类,提供大小写转换、判断等方法

大数据类

说明
BigInteger 任意大小整数
BigDecimal 高精度浮点数

Math类

常用方法:abs()max()min()sqrt()pow()ceil()floor()round()

Random类

Random r = new Random();
r.nextInt();      // 随机整数
r.nextInt(n);     // 0~n-1随机整数
r.nextDouble();   // 随机浮点数

25.2 面试题精选

基础题

1. Java变量类型及选择

题目

请列举Java中的基本数据类型,并说明在实际开发中如何选择合适的类型。

深入解析

Java基本数据类型分为四大类:

整型:byte(1字节)、short(2字节)、int(4字节)、long(8字节)
浮点型:float(4字节)、double(8字节)
字符型:char(2字节)
布尔型:boolean

选择原则:

  1. 整数优先用int:范围足够大(-21亿~21亿),性能好
  2. 大整数用long:超过int范围时使用,如时间戳毫秒数
  3. 小范围用byte/short:内存敏感场景,如大量数据存储
  4. 小数优先用double:精度足够,默认小数类型
  5. 金钱计算用BigDecimal:避免精度丢失
int userId = 10001;           // ID用int
long timestamp = System.currentTimeMillis();  // 时间戳用long
byte age = 25;                // 年龄用byte节省内存
double price = 99.99;         // 价格用double
BigDecimal money = new BigDecimal("10000.00");  // 金融计算用BigDecimal

注意:Java没有无符号类型,Java 8新增部分无符号方法但使用较少。

答题示例

Java基本类型分整型、浮点型、字符型、布尔型。

整型有 byte、short、int、long,浮点型有 float、double。

选择时:整数优先用 int,不够用 long;小数用 double;金钱计算用 BigDecimal 避免精度问题。

参考文章
  • 3.变量相关

2. String比较方式

题目

Java中判断两个字符串内容是否相等应该用什么方式?为什么不能用==

深入解析

Java中==equals()的区别:

==运算符

  • 基本类型:比较值是否相等
  • 引用类型:比较引用地址是否相同

equals()方法

  • 比较字符串内容是否相等
  • equalsIgnoreCase()忽略大小写比较

字符串创建方式的影响

String s1 = "hello";      // 字符串常量池
String s2 = "hello";      // 指向同一引用
String s3 = new String("hello");  // 堆中新建对象

s1 == s2;     // true,同一引用
s1 == s3;     // false,不同引用
s1.equals(s3); // true,内容相同

直接赋值时,相同字符串指向同一引用(字符串常量池);new String()每次都创建新对象。

答题示例

== 比较引用地址,equals() 比较内容。

直接赋值的相同字符串指向同一引用,new String() 每次都新建对象。

所以判断字符串内容要用 equals(),忽略大小写用 equalsIgnoreCase()

参考文章
  • 15.字符串-String

进阶题

1. ArrayList与LinkedList的区别

题目

请说明ArrayList和LinkedList的区别,以及在什么场景下选择哪个?

深入解析

两者都实现List接口,方法使用一致,但底层结构不同:

特性 ArrayList LinkedList
底层结构 动态数组 双向链表
随机访问 O(1),高效 O(n),需遍历
头部插入删除 O(n),需移动元素 O(1),只需改指针
中间插入删除 O(n) O(n),需先遍历定位
内存占用 连续空间 每个节点额外存储前后指针

选择建议

  • ArrayList:查询多、修改少,如配置列表、数据展示
  • LinkedList:频繁在头部或中间插入删除,如消息队列
// 查询场景用ArrayList
List<User> userList = new ArrayList<>();
userList.get(0);  // O(1)

// 频繁头部插入用LinkedList
LinkedList<Message> queue = new LinkedList<>();
queue.addFirst(new Message());  // O(1)
答题示例

ArrayList 底层是数组,随机访问快 O(1),但插入删除要移动元素。

LinkedList 底层是链表,头部插入删除快 O(1),但随机访问要遍历。

查询多用 ArrayList,频繁头部插入删除用 LinkedList。

参考文章
  • 18.集合类-ArrayList和LinkedList

2. HashMap与TreeMap的区别

题目

HashMap和TreeMap有什么区别?什么情况下使用TreeMap?

深入解析

两者都实现Map接口,以键值对存储数据:

特性 HashMap TreeMap
底层结构 哈希表 红黑树
顺序 无序 按键排序
null键 允许 不允许
查找效率 O(1) O(log n)
插入效率 O(1) O(log n)

使用场景

  • HashMap:不需要排序,追求性能,绝大多数场景
  • TreeMap:需要按键排序,如排行榜、按时间范围查询
// 一般场景用HashMap
Map<Integer, User> userMap = new HashMap<>();

// 需要排序时用TreeMap
TreeMap<String, Integer> scores = new TreeMap<>();
scores.put("Alice", 90);
scores.put("Bob", 85);
// 遍历时按键字典序排序输出
答题示例

HashMap 基于哈希表,无序,查找 O(1),允许 null 键。

TreeMap 基于红黑树,按键排序,查找 O(log n),不允许 null 键。

一般用 HashMap,需要排序时才用 TreeMap。

参考文章
  • 20.集合类-HashMap和TreeMap

3. Java多态与C#的区别

题目

Java中的方法重写与C#有什么区别?

深入解析

Java多态特点

  • 方法默认可被重写(除非声明为final
  • @Override注解可选,但推荐使用(编译器检查)
  • 使用super调用父类方法

C#多态特点

  • 必须用virtual标记可重写方法
  • 子类必须用override显式重写
  • 使用base调用父类方法
// Java
class Father {
    public void eat() { }  // 默认可重写
}

class Son extends Father {
    @Override
    public void eat() {
        super.eat();  // 调用父类
    }
}
// C#
class Father {
    public virtual void Eat() { }  // 必须标记virtual
}

class Son : Father {
    public override void Eat() {   // 必须用override
        base.Eat();
    }
}

关键区别:Java方法默认虚方法,C#需显式声明。

答题示例

Java 方法默认可重写,除非声明 final@Override 注解可选但推荐。

C# 必须用 virtual 标记可重写方法,子类用 override 显式重写。

Java 用 super 调用父类,C# 用 base

参考文章
  • 12.面向对象-多态

深度题

1. HashSet与TreeSet的底层实现及选择

题目

HashSet和TreeSet的底层实现原理是什么?如何选择?

深入解析

HashSet底层

  • 基于HashMap实现,元素作为key存储
  • value是一个固定的Object对象
  • 通过hashCode()和equals()保证唯一性
  • 查找、插入、删除都是O(1)

TreeSet底层

  • 基于TreeMap实现,元素作为key存储
  • 使用红黑树存储,自动排序
  • 元素必须实现Comparable接口或传入Comparator
  • 查找、插入、删除都是O(log n)

选择依据

// 去重场景,不关心顺序
Set<String> tags = new HashSet<>();  // O(1)效率高

// 需要排序或范围查询
TreeSet<Integer> scores = new TreeSet<>();
scores.add(90);
scores.add(85);
scores.first();      // 最小值
scores.last();       // 最大值
scores.headSet(90);  // 小于90的元素

自定义排序

class User implements Comparable<User> {
    int score;
    public int compareTo(User o) {
        return this.score - o.score;  // 按分数排序
    }
}
答题示例

HashSet 基于哈希表,O(1) 效率,无序,通过 hashCode 和 equals 去重。

TreeSet 基于红黑树,O(log n),自动排序,元素需实现 Comparable 或传入 Comparator。

只需去重用 HashSet,需要排序或范围查询用 TreeSet。

参考文章
  • 19.集合类-HashSet和TreeSet

2. Lambda表达式与函数式接口

题目

Java中的Lambda表达式是如何工作的?什么是函数式接口?

深入解析

Lambda表达式本质

  • Lambda表达式是匿名内部类的语法糖
  • 必须与函数式接口配合使用
  • 函数式接口 = 只包含一个抽象方法的接口

语法

(参数) -> { 代码块 }
参数 -> 结果表达式

函数式接口

@FunctionalInterface  // 可选注解,编译器检查
interface ICalculator {
    int calculate(int a, int b);
}

ICalculator add = (a, b) -> a + b;
ICalculator multiply = (a, b) -> a * b;

Java内置函数式接口(java.util.function):

  • Function<T, R>:接收T返回R
  • Consumer<T>:接收T无返回
  • Supplier<T>:无参数返回T
  • Predicate<T>:接收T返回boolean
Function<Integer, String> f = x -> "值:" + x;
String result = f.apply(100);  // "值:100"

注意:Lambda内不能修改局部变量(effectively final),可修改外部类成员变量。

答题示例

Lambda 是匿名内部类的语法糖,必须配合函数式接口使用。

函数式接口是只包含一个抽象方法的接口。

Java 内置了 Function、Consumer、Supplier、Predicate 等常用函数式接口。

注意 Lambda 内不能修改局部变量。

参考文章
  • 22.lambda表达式
  • 23.方法的引用和Function接口

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏