rookie-Java

基础

BigDecimal

divide

在 Java 中,BigDecimal 类提供了 divide 方法用于执行除法运算。divide 方法有多个重载版本,可以用于执行不同类型的除法操作。

方法签名:

1
public BigDecimal divide(BigDecimal divisor)

参数说明:

  • divisor:除数,表示要将当前 BigDecimal 对象除以的值。

方法返回值:

  • 返回一个新的 BigDecimal 对象,表示当前 BigDecimal 对象除以 divisor 后的结果。

除了上述的简单版本,BigDecimaldivide 方法还有其他重载版本,可以用于指定除法运算的精度(小数位数)和舍入模式。以下是一个带有精度和舍入模式参数的重载版本:

方法签名:

1
public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode)

参数说明:

  • divisor:除数,表示要将当前 BigDecimal 对象除以的值。
  • scale:指定除法运算的精度,即结果的小数位数。
  • roundingMode:舍入模式,用于处理除不尽的情况。

方法返回值:

  • 返回一个新的 BigDecimal 对象,表示当前 BigDecimal 对象除以 divisor 后的结果,并根据指定的精度和舍入模式进行舍入。

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
public void test() {
BigDecimal num1 = new BigDecimal("10");
BigDecimal num2 = new BigDecimal("3");

// 简单的除法运算
BigDecimal result1 = num1.divide(num2);
System.out.println(result1); // 输出:3.333333333333333333333333333333333333333333333333333333333333

// 指定精度和舍入模式的除法运算
BigDecimal result2 = num1.divide(num2, 2, RoundingMode.HALF_UP);
System.out.println(result2); // 输出:3.33
}

在上述示例中,我们创建了两个 BigDecimal 对象 num1num2,然后进行了除法运算。首先使用简单的 divide 方法进行除法运算,得到的结果是一个无限循环的小数。接着,我们使用带有精度和舍入模式参数的 divide 方法,将结果舍入到小数点后两位,得到了结果 “3.33”。可以看到,指定精度和舍入模式可以控制除法运算结果的精确度。

总结:BigDecimal 类的 divide 方法可以用于执行除法运算,并且提供了多个重载版本,以支持不同精度和舍入模式的除法计算。

容器

Map

merge

Map 接口中的 merge 方法用于合并两个映射中的键值对。它可以用于向一个 Map 中添加新的键值对,或者更新已有键对应的值。

方法签名如下:

1
V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)

参数说明:

  • key: 要合并的键。

  • value:要合并的值。

  • remappingFunction:合并函数,用于处理重复的键值对。它是一个函数式接口

    BiFunction,接受两个参数,并返回一个值。该函数接收两个参数:

    • existingValue:当前 Map 中与指定键关联的值(如果存在),如果键不存在则为 null。
    • newValue:要合并的值。

方法返回值:

  • 方法返回合并后的值。如果指定的键在当前 Map 中不存在,或与指定键关联的值为 null,则将指定的键值对直接添加到当前 Map 中,并返回要合并的值。

    如果指定的键在当前 Map 中存在,并且与指定键关联的值不为 null,则使用合并函数处理重复的键值对,并返回合并后的值。

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
public void test() {
Map<String, Integer> inventory = new HashMap<>();
inventory.put("apple", 10);

String productName = "apple";
int additionalQuantity = 20;

// 合并新的库存量到 Map 中
inventory.merge(productName, additionalQuantity,
(existingQuantity, newQuantity) -> existingQuantity + newQuantity);

System.out.println(inventory); // 输出:{apple=30}
}

在上述示例中,我们首先创建了一个 HashMap,其中包含了产品名称和库存量的映射。接着,我们希望将新的库存量(20)合并到 Map 中的 “apple” 产品中。使用 merge 方法,我们找到 “apple” 对应的库存量(10),然后将新的库存量(20)与当前库存量相加得到 30,并将其更新到 Map 中。最终的结果是 inventory 中包含键值对 “apple=30”。

这就是 Map 接口中 merge 方法的使用方法。它是一个很实用的方法,可以方便地处理 Map 中的键值对合并和更新操作。

getOrDefault

getOrDefault 用于获取 Map 中指定键的值,如果键不存在于 Map 中,则返回一个默认值。

方法签名如下:

1
V getOrDefault(Object key, V defaultValue);

参数说明:

  • key:要获取值的键。
  • defaultValue:如果键不存在时要返回的默认值。

方法返回值:

  • 如果 key 存在于 Map 中,则返回与键关联的值。
  • 如果 key 不存在于 Map 中,则返回默认值defaultValue

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void test() {
Map<String, Integer> map = new HashMap<>();

// 向 Map 中添加键值对
map.put("key1", 24);
map.put("key2", 100);

// 获取指定键的值,如果键不存在则返回默认值
int value1 = map.getOrDefault("key1", 0);
int value3 = map.getOrDefault("key3", 0);

System.out.println("Value1: " + value1); // 输出 24
System.out.println("Value3: " + value3); // 输出 0,因为 "key3" 不存在于 Map 中
}

在这个示例中,首先向 Map 中添加了两个键值对 (“key1”, 42) 和 (“key2”, 100)。然后使用 getOrDefault 方法来获取键 “key1” 的值,它存在于 Map 中,所以返回值为 42。接着尝试获取键 “key3” 的值,但由于 “key3” 不存在于 Map 中,所以返回默认值 0。

computeIfPresent

computeIfPresent 方法用于根据指定的键和值更新 Map 中的值,但仅当键存在且对应的值非空时才进行更新。如果键不存在或对应的值为空,则不执行更新操作。

方法签名如下:

1
V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction);

参数说明:

  • key 表示要更新值的键。
  • remappingFunction 是一个函数,接受两个参数:键 K 和当前键对应的值 V,并返回一个新的值 V 用于更新。

方法返回值:

  • 如果 key 存在于 Map 中,且对应的值非空,根据 remappingFunction 函数计算生成新值,并返回新值。
  • 如果 key 不存在于 Map 中,则返回 null。

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void test() {
Map<String, Integer> map = new HashMap<>();

// 向 Map 中添加键值对
map.put("key1", 24);
map.put("key2", 100);

// 使用 computeIfPresent 方法更新键 "key1" 的值
map.computeIfPresent("key1", (key, value) -> value + 10);

// 使用 computeIfPresent 方法更新键 "key3" 的值(键 "key3" 不存在,不执行更新)
map.computeIfPresent("key3", (key, value) -> value + 10);

System.out.println("Value of key1: " + map.get("key1")); // 输出 34,因为更新了键 "key1"
System.out.println("Value of key3: " + map.get("key3")); // 输出 null,因为键 "key3" 不存在
}

在这个示例中,首先向 Map 中添加了两个键值对 (“key1”, 24 和 (“key2”, 100)。然后使用 computeIfPresent 方法尝试更新键 “key1” 的值,因为 “key1” 存在于 Map 中,所以更新了值为 34。接着尝试更新键 “key3” 的值,但由于 “key3” 不存在于 Map 中,所以不执行更新操作。

computeIfAbsent

computeIfAbsent 用于根据指定的键获取对应的值,如果键不存在,则通过一个函数计算生成新值并将其放入到 Map 中。

方法签名如下:

1
V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)

参数说明:

  • key:要获取值的键。
  • mappingFunction:生成新值的函数,它是一个函数式接口 Function,接受一个参数(即键 key),并返回生成的新值。

方法返回值:

  • 如果 key 存在于 Map 中,则返回与键关联的值。
  • 如果 key 不存在于 Map 中,则根据 mappingFunction 函数计算生成新值,并将新键值对添加到 Map 中,并返回新值。

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
public void test() {
Map<String, Integer> inventory = new HashMap<>();
inventory.put("apple", 10);

String productName = "banana";

// 获取指定键对应的值,如果键不存在则使用函数生成新值
int quantity = inventory.computeIfAbsent(productName, key -> 0);

System.out.println(inventory); // 输出:{apple=10, banana=0}
System.out.println(quantity); // 输出:0
}

在上述示例中,我们首先创建了一个 HashMap,其中包含了产品名称和库存量的映射。接着,我们尝试使用 computeIfAbsent 方法获取键 “banana” 对应的值,由于该键不存在于 inventory 中,因此根据提供的 mappingFunction 函数计算生成新值 0,并将新的键值对 “banana=0” 添加到 inventory 中,并返回新值 0。

注意,computeIfAbsent 方法在获取值时会检查键是否存在,如果键已存在,则不会执行 mappingFunction 函数。如果键不存在,则会执行 mappingFunction 函数生成新值并添加到 Map 中。

这就是 Map 接口中 computeIfAbsent 方法的使用方法。它非常方便,可以在需要根据键来生成新值并添加到 Map 中的场景中使用。

putIfAbsent

putIfAbsent 用于向 Map 中添加键值对,但仅当指定的键在 Map 中不存在时才执行添加操作。如果指定的键已经存在,方法不会执行添加操作,而是返回已存在的值。

方法签名如下:

1
V putIfAbsent(K key, V value);

参数说明:

  • key:表示要添加的键。
  • value:表示要添加的值。

方法返回值:

  • 如果 key 存在于 Map 中,方法不会执行添加操作,返回已存在的值。
  • 如果 key 不存在于 Map 中,则返回 null。

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void test() {
Map<String, Integer> map = new HashMap<>();

// 添加键值对,如果键不存在
Integer oldValue = map.putIfAbsent("key", 24);
System.out.println("Old Value: " + oldValue); // 输出 null,表示添加成功

// 再次尝试添加相同的键值对
Integer existingValue = map.putIfAbsent("key", 100);
System.out.println("Existing Value: " + existingValue); // 输出 24,表示键已存在,不执行添加操作

// 查看最终结果
System.out.println("Map: " + map); // 输出:Map: {key=24}
}

在上述示例中,首先尝试向 Map 中添加键值对 “key” 和 24,因为键 “key” 不存在,所以添加成功,返回值为 null。然后再次尝试添加相同的键值对,但由于键 “key” 已经存在,不执行添加操作,返回已存在的值 24。最终,Map 中只包含一个键值对 {key=24}。

这个方法的主要目的是在多线程环境中避免竞态条件(race condition),确保只有一个线程成功地将键值对添加到 Map 中。

Collections

singletonList

Collections 类中的 singletonList 方法用于创建一个包含单个元素的不可变(immutable)列表(List)。这个列表只包含一个元素,长度固定为 1,因此无法对其进行添加或删除元素的操作。

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
// 使用 singletonList 方法创建一个包含单个元素的不可变列表
String singleElement = "Hello";
List<String> list = Collections.singletonList(singleElement);

// 尝试修改列表内容,将会抛出 UnsupportedOperationException 异常
// list.add("World"); // 试图修改不可变列表,抛出异常

// 访问列表元素
System.out.println("List contains: " + list.get(0)); // 输出: List contains: Hello
System.out.println("List size: " + list.size()); // 输出: List size: 1
}

在上述代码中,我们首先使用 singletonList 方法创建一个包含单个元素 “Hello” 的不可变列表。由于该列表是不可变的,试图使用 add 方法添加元素 “World” 将会抛出 UnsupportedOperationException 异常。

singletonList 方法在一些情况下非常有用,特别是当我们需要创建只包含一个元素的列表,并且希望保证列表内容不会被改变时。请注意,由于返回的列表是不可变的,因此在实际使用时,我们要确保不会对该列表进行修改操作。


rookie-Java
https://arloyee.github.io/2023/07/29/rookie-Java/
作者
YaYee
发布于
2023年7月29日
许可协议