Objects, Immutability, and Switch Expressions 40-48
本文为《Java Coding Problems》40-48题,问题涉及Objects, Immutability, and Switch Expressions (共18题)。
40. 函数式和过程式的判空
问题:null的判断。
思路:使用object != null
,或者Objects.isNull
、Objects.nonNull
。
代码如下:
// 判断列表中是否有null (过程式)
public boolean hasNull(List<Integer> integerList) {
if (integerList == null) {
return false;
}
for (Integer integer : integerList) {
if (integer == null) {
return true;
}
}
return false;
}
}
// 判断列表中是否有null (函数式)
public boolean hasNull(List<Integer> integerList) {
return Objects.nonNull(integerList) &&
integerList.stream()
.anyMatch(Objects::isNull);
}
41. 检查null引用,并抛出自定义NullPointerException
问题:检查null引用,并抛出自定义NullPointerException
。
思路:使用if
检查,使用throw new NullPointerException
抛出异常,或者使用Objects.requireNonNull
。
代码如下:
public void nullTest() {
String name = null;
if (name == null) {
throw new NullPointerException("Name cannot be null!");
}
// 等价于if (name == null) throw new ...
Objects.requireNonNull(name, "Name cannot be null!");
}
42. 检查null引用,并抛出特定异常
问题:检查null引用,并抛出特定异常。
思路:使用if
检查,然后抛出异常。
43. 检查null引用,并设置默认值
问题:检查null饮用,并在为null的时候设置默认值。
思路:使用if
检查,并设置默认值,或使用Objects.requireNonNullElseGet
。
代码如下:
public void nullTestSetDefaultValue() {
String name = null;
if (name == null) {
name = "default name";
}
// 等价于if (name == null) name = ...
name = Objects.requireNonNullElse(name, "default name");
}
44. 检查索引范围是否在[0, length)范围内
问题:检查给定索引是否在[0, length)
范围内。
思路:使用Objects.checkIndex
检查(JDK9)。
45. 检查索引段是否在[0, length)范围内
问题:检查索引段是否在[0, length)范围内。
思路:使用Objects.checkFromToIndex
检查(JDK9)。
46. 说明equals
和hashCode
如何工作
问题:说明equals
和hashCode
在java中如何工作
思路:说明。
用途说明:
equals
和hashCode
是每个类都有的方法。Equals
用于比较对象,hashCode
用于生成类的hash值。
默认实现:
equals
默认实现是检查两个对象是否是同一个(内存地址相同),内部使用==
实现。hashCode
默认实现返回对象的内存地址。
重写实现
equals
实现需要满足5个性质:
- 自反性:对象总是等于自身。
p1.equals(p1)
总是返回true
。 - 对称性:
p1.equals(p2)
和p2.equals(p1)
结果相同。 - 传递性:如果
p1.equals(p2)
,p2.equals(p3)
,那么p1.equals(p3)
。 - 一致性:两个对象如果相等,那么只要两个对象没改动,他们会一直相等。
- 不等于
Null
: 所有对象与null
,不相等。 代码如下:
@Override
public boolean equals(Object obj) {
if (this == obj) {
// 自反性
return true;
}
if (obj == null) {
// 不等于Null
return false;
}
if (getClass() != obj.getClass()) {
// 类型相同
return false;
}
// 其他属性比较
// ...
return true;
}
hashCode
实现需要满足:
- 两个相等的对象,必须返回相同的hash code。
- 只要对象不发生改变,必须返回相同的hash code。 因此:
- 当重写
equals
方法,必须重写hashCode
方法。 - 在两个方法中必须使用相同的属性集。
47. 解释不可变对象
问题:解释不可变对象。
思路:说明。
- 基本类型是不可变的。
- 一些常用类,比如
String
,Pattern
,LocalDate
是不可变的。 - 数组是不可变的。
- Collections可以是可变的,不可修改的,或不可变的。 不可变对象在多线程环境中常用,因为它不会引起并发中的一些常见问题。
48. 不可变字符串
问题:字符串是不可变的,这样设计有什么好处?
思路:说明。
不可变的优势
字符串常量池:
在创建字符串常量时,所有的字符串常量会被保存在字符串常量池中,代码如下:
public static void internString() {
String t1 = "Hello";
String t2 = "Hello";
String t3 = "Hello";
if (t1 == t2 && t2 == t3) {
// t1, t2, t3指向常量池中的同一个对象
System.out.println("All String points to same memory address");
}
String t4 = new String("Hello");
if (t3 != t4) {
// 通过new String创建的对象在堆中
System.out.println("Not interned");
}
t4 = t4.intern();
if (t3 == t4) {
// 手动调用intern产生一个指向常量池对象的引用
System.out.println("Interned");
}
}
安全:
字符串不可变可以防止很多攻击。在使用Class.forName
时不会遭受String
改变的问题。
线程安全:
字符串可以在多个线程中共享,是线程安全的。
hash code缓存:
可以缓存hash code。
不可变的缺点
无法继承
无法通过继承为String添加更多功能。
安全问题
如果通过String
保存敏感数据,那这些数据可能长时间存在于字符串常量池中,存在安全隐患。
内存溢出
字符串常量池不大,可能导致内存溢出错误。
相关文章
- AT2172 [AGC007E] Shik and Travel
- 【阅读】A Comprehensive Survey on Electronic Design Automation and Graph Neural Networks——EDA+GNN综述翻译
- ORA-22333: cannot reset type “string”.”string” due to invalid dependent types and tables ORACLE 报错 故障修复 远程处理
- ORA-25198: only range, list, and hash partitioning are supported for index-organized table ORACLE 报错 故障修复 远程处理
- ORA-26820: string capture server for apply “string” and propagation “string” becomes active and needs join capture process “string”. ORACLE 报错 故障修复 远程处理
- ORA-38475: The attribute set and the associated ADT are out of sync. ORACLE 报错 故障修复 远程处理
- MySQL Error number: MY-010465; Symbol: ER_RPL_BINLOG_MASTER_USES_CHECKSUM_AND_SLAVE_CANT; SQLSTATE: HY000 报错 故障修复 远程处理
- ORA-03222: average row size and row count must be greater than zero ORACLE 报错 故障修复 远程处理
- MySQL Error number: MY-013863; Symbol: ER_IB_MSG_LOG_FILES_CREATED_BY_CLONE_AND_READ_ONLY_MODE; SQLSTATE: HY000 报错 故障修复 远程处理
- Create a nice looking chart with CL_GUI_CHART_ENGINE – Part 3 – Chart Data and render详解编程语言
- 多条件查询MySQL中使用And多条件查询的步骤(mysql中and)
- Maximizing Performance: Harnessing the Power of Redis and Spring Framework(redisspring)
- Building a robust application with SSM and MongoDB: A guide to seamless integration.(ssmmongodb)
- MySQL中的AND逻辑操作符是什么(mysql中and是什么)
- MySQL中如何正确使用AND运算符(mysql中and怎么用)
- MySQL中的AND和OR使用逻辑运算符优化查询语句(mysql中and与or)
- Oracle中使用除了And的其他查询关键字(oracle中除了and)
- Oracle中使用AND运算符的示例分析(oracle中and用法)
- Oracle与顺序提升数据处理速率(oracle and顺序)