深入解析Guava范围类(Range)

news2024/11/25 7:11:34

在这里插入图片描述

在这里插入图片描述

第1章:范围类Range的重要性

大家好,我是小黑,今天咱们聊聊一个在Java编程世界里非常实用但又被低估的角色——Guava库中的Range类。你知道吗,在处理涉及到数值范围的问题时,Range类就像是咱们的救星。不论是判断某个数字是否在一个特定区间内,还是在数据筛选和验证的场景中,Range都能大放异彩。

那为什么要使用Guava的Range,而不是自己辛辛苦苦从头实现呢?咱们来看几个点:

  1. 减少错误:自己写代码容易出错,尤其是处理边界条件时。Guava的Range经过了广泛测试,稳定性和可靠性更高。
  2. 代码简洁:用Range处理区间问题,代码会更简洁明了。这样一来,维护和理解代码就容易多了。
  3. 功能丰富:Range提供了很多内置方法,比如判断是否包含某个值、求两个区间的交集等,功能强大,使用方便。

咱们可能在处理用户年龄、商品价格区间,甚至是在制定策略规则时,都需要用到范围类。Range就像是一个多面手,无论在哪个领域都能派上用场。

第2章:Range类的基本概念

咱们来看看什么是Range。简单来说,Range是Guava提供的一个类,用于表示一个不可变的范围,或者说是区间。这个区间可以是任何Comparable类型,比如整数、浮点数,甚至是日期。

创建Range对象的方式多种多样,但最常用的无非就是开区间、闭区间这些。举个例子,如果咱们要表示一个包含1到5的整数区间,可以这么写:

Range<Integer> range1 = Range.closed(1, 5); // 闭区间,包含1和5

如果是开区间,不包括边界值,就可以这样:

Range<Integer> range2 = Range.open(1, 5); // 开区间,不包含1和5

当然了,Guava还提供了更多灵活的方式来创建Range,比如只有一边的区间:

Range<Integer> range3 = Range.greaterThan(10); // 大于10
Range<Integer> range4 = Range.atMost(5); // 最大值为5

咱们再来看看如何使用Range。假设小黑手头有个需求,要判断一个数字是否在某个区间内,用Range就能轻松搞定:

Range<Integer> range = Range.closed(1, 10); // 1到10的闭区间
boolean isInRange = range.contains(5); // 判断5是否在这个区间内

这样一来,判断数字是否在一个特定的区间内就简单多了。而且,Range的方法还有很多,比如encloses判断一个范围是否包含另一个范围,isConnected判断两个范围是否相连,这些都是在实际编程中非常有用的工具。

第3章:深入Range的操作方法

1. 判断值是否在范围内

最基本也最常用的功能就是判断某个值是否在Range指定的范围内。这在数据验证或条件判断时特别有用。看下面的例子:

Range<Integer> ageRange = Range.closed(18, 60); // 定义一个18到60岁的年龄范围
boolean isEligible = ageRange.contains(30); // 检查30岁是否在这个范围内
2. 检查范围是否相连

有时候,咱们需要知道两个范围是否有交集。Range提供了isConnected方法来判断这一点:

Range<Integer> range1 = Range.closed(1, 5);
Range<Integer> range2 = Range.closed(5, 10);
boolean isConnected = range1.isConnected(range2); // 判断range1和range2是否相连

这里,isConnected会返回true,因为两个范围在5这个点上相连。

3. 范围的交集

当两个范围相连时,咱们可能想要知道它们的交集是什么。Range的intersection方法可以帮助咱们找到这个交集:

Range<Integer> intersection = range1.intersection(range2); // 获取range1和range2的交集

在这里插入图片描述

4. 范围的并集

除了找交集,有时咱们还需要合并两个范围。这时,span方法就派上用场了:

Range<Integer> span = range1.span(range2); // 获取覆盖range1和range2的最小Range

5. 处理无界范围

Range不仅仅能处理有界的范围,它还能处理无界的范围,比如大于某个值或小于某个值的范围:

Range<Integer> greaterThanTen = Range.greaterThan(10); // 大于10
Range<Integer> atMostFive = Range.atMost(5); // 小于等于5
6. 离散域范围

Range还支持离散域的概念。比如,咱们可以获得一个范围内所有整数的集合:

Range<Integer> oneToFive = Range.closed(1, 5);
Set<Integer> numbers = ContiguousSet.create(oneToFive, DiscreteDomain.integers());
// 现在numbers包含了1, 2, 3, 4, 5

通过上面的例子,咱们可以看到,Range的操作方法非常多样和强大。它不仅能处理简单的范围判断,还能处理更复杂的场景,比如范围的交集、并集,甚至是处理无界范围和离散域。这些功能使得Range成为处理数值范围时的得力助手。

第4章:Range类与数学概念的联系

咱们已经看到了Range的一些基本操作,但小黑要告诉你的是,Range的魅力远不止于此。它其实与数学中的区间概念密切相关,这一点在处理复杂算法或数据分析时尤其有用。让咱们来深入探讨一下这个话题。

数学中的区间概念

在数学中,区间是一系列数的集合,通常定义为某个范围内的所有数。这些区间可以是开放的(不包括端点),闭合的(包括端点),或者半开半闭的(一端开放,一端闭合)。比如,“小于5”的区间在数学上表示为 (-∞, 5),而“小于等于5”的区间表示为 (-∞, 5]。

Range与数学区间的映射

在Guava的Range中,这些数学概念得到了很好的体现。比如,咱们可以用Range来表示上述的数学区间:

Range<Integer> lessThanFive = Range.lessThan(5); // (-∞, 5)
Range<Integer> upToFive = Range.atMost(5); // (-∞, 5]

这样的映射让Range在处理数学问题时变得异常强大。

复杂算法中的应用

在一些复杂的算法中,比如在统计学或者金融计算中,区间的概念经常出现。比如,咱们可能需要分析某个特定收入区间内的用户行为。使用Range,这些问题就变得易于处理:

Range<BigDecimal> incomeRange = Range.closed(new BigDecimal("10000"), new BigDecimal("50000"));
// 表示收入在10000到50000之间的范围

在这个例子中,Range帮助咱们定义了一个精确的数值范围,并可以用来过滤或分析数据。

数学操作的实际应用

除了直接映射数学区间,Range还可以用于各种实际的数学操作。比如,在数据分析中,咱们可能需要找出两个数据集的重叠部分。使用Range的交集操作就可以轻松实现:

Range<Integer> dataRange1 = Range.closed(1, 10);
Range<Integer> dataRange2 = Range.closed(5, 15);
Range<Integer> overlap = dataRange1.intersection(dataRange2);
// overlap就是两个数据集的重叠部分,即5到10

通过这个例子,咱们可以看到,Range不仅仅是一个编程工具,它还是一个强大的数学工具,能帮助咱们处理复杂的数学问题。

到目前为止,咱们已经探讨了Range在数学概念中的应用,以及它如何帮助咱们在编程中处理复杂的数学问题。这些知识对于理解Range的工作原理和应用场景是非常重要的。希望通过这章的内容,大家能够更好地理解和利用Range的强大功能。

第5章:Range的边界处理

咱们来聊聊Range在处理边界时的一些技巧和最佳实践。在使用Range时,处理开区间和闭区间的细节至关重要,尤其是当咱们的应用需要精确控制边界值时。让小黑带你深入了解如何在Guava的Range中处理这些情况。

1. 开区间和闭区间的区别

首先,咱们得清楚开区间(open)和闭区间(closed)的区别。闭区间包含其边界值,而开区间不包含。比如,Range.closed(1, 5)表示一个包括1和5的区间,而Range.open(1, 5)则表示一个不包括1和5的区间。这个区别虽小,但却关系重大,尤其在处理边界条件时:

Range<Integer> closedRange = Range.closed(1, 5); // 包括1和5
boolean contains1 = closedRange.contains(1); // 返回true

Range<Integer> openRange = Range.open(1, 5); // 不包括1和5
boolean contains1InOpen = openRange.contains(1); // 返回false
2. 处理边界值

处理边界值是Range使用中的一个关键点。特别是在数据过滤或者条件判断时,正确理解和应用边界值非常重要。比如,咱们想要一个区间包含下限但不包含上限,就可以使用半开半闭区间:

Range<Integer> halfOpenRange = Range.closedOpen(1, 5); // 包括1,但不包括5
3. 特殊边界的处理

有些时候,咱们可能需要处理一些特殊的边界情况,比如无限区间。Guava的Range支持无界区间,比如greaterThan(大于)、atMost(最大值)等方法。这些方法允许咱们创建没有明确边界的区间:

Range<Integer> greaterThanTen = Range.greaterThan(10); // 大于10的区间
Range<Integer> atMostFive = Range.atMost(5); // 最大为5的区间
4. 边界条件的实用性

理解和正确使用边界条件对于编写健壮和精确的代码至关重要。比如,在金融应用中,可能需要精确控制交易范围,或者在数据科学领域,可能需要精确地过滤数据集。在这些场景下,精确的边界控制是必不可少的。

5. 代码示例:数据过滤

让我们来看一个实际的例子,如何使用Range进行数据过滤:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Range<Integer> range = Range.closedOpen(3, 7); // 3到7的区间,包含3但不包含7

List<Integer> filteredNumbers = numbers.stream()
    .filter(range::contains)
    .collect(Collectors.toList());
// 结果将是 [3, 4, 5, 6]

在这个例子中,咱们利用了Range来过滤一个数字列表,只保留那些在特定区间内的数字。

第6章:范围的组合与分割

1. 范围的组合:求并集

在很多情况下,咱们需要将两个范围合并为一个。Guava的Range类提供了span方法来实现这一点。这个方法会返回一个新的Range,覆盖所有原始Range包含的值。

Range<Integer> range1 = Range.closed(1, 3); // 1到3的闭区间
Range<Integer> range2 = Range.closed(5, 7); // 5到7的闭区间
Range<Integer> spanRange = range1.span(range2); // 覆盖1到7的范围

在这个例子中,spanRange现在表示的是1到7的闭区间,即使两个原始范围之间有空隙。

2. 范围的交集:求共有部分

另一个常见需求是找到两个范围的共有部分,即交集。Range的intersection方法可以帮助咱们实现这个功能。

Range<Integer> range3 = Range.closed(3, 6); // 3到6的闭区间
Range<Integer> intersectionRange = range1.intersection(range3); // 3到3的闭区间

在这个例子中,intersectionRange代表3到3的闭区间,即两个范围共有的部分。

3. 范围的分割:断开和限制

有时候,咱们可能需要在特定点分割一个范围,或者限制它的上下界。虽然Guava的Range类没有直接提供分割方法,但咱们可以通过组合方法来实现这个功能。

Range<Integer> bigRange = Range.closed(1, 10); // 1到10的闭区间
Range<Integer> lowerPart = bigRange.intersection(Range.atMost(5)); // 1到5的闭区间
Range<Integer> upperPart = bigRange.intersection(Range.greaterThan(5)); // 6到10的闭区间

在这个例子中,lowerPartupperPart分别表示原始范围的下半部分和上半部分。

4. 实际应用案例

想象一下,如果咱们正在开发一个电商平台,可能需要根据价格区间来筛选商品。利用Range的这些组合和分割操作,咱们可以轻松实现这一功能。

List<BigDecimal> prices = // ... 获取商品价格列表
Range<BigDecimal> promoRange = Range.closed(new BigDecimal("50.00"), new BigDecimal("100.00")); // 促销价格区间
List<BigDecimal> promoPrices = prices.stream()
    .filter(promoRange::contains)
    .collect(Collectors.toList());
// 现在promoPrices包含了所有在促销区间内的商品价格

第7章:Range与Guava其他类的交互

1. Range与集合类的结合

Range可以和Guava提供的各种集合类结合使用,比如ImmutableListSets等。这种结合可以用于创建特定条件下的集合,或者对集合进行过滤。

比如,咱们可以使用Range来筛选集合中符合特定条件的元素:

Range<Integer> validRange = Range.closed(1, 10);
List<Integer> numbers = ImmutableList.of(0, 2, 5, 15, 20);
List<Integer> filteredNumbers = numbers.stream()
    .filter(validRange::contains)
    .collect(Collectors.toList());
// 结果将是 [2, 5]

在这个例子中,只有集合中的部分元素符合Range定义的条件。

2. Range与函数式编程接口的结合

Guava强大的函数式编程接口,如FunctionPredicate,也可以与Range结合使用。这种结合使得Range在复杂的数据处理和转换操作中更加灵活。

比如,咱们可以结合使用Predicate和Range来创建复杂的过滤条件:

Predicate<Integer> inRange = validRange::contains;
List<Integer> evenNumbersInRange = numbers.stream()
    .filter(inRange.and(n -> n % 2 == 0))
    .collect(Collectors.toList());
// 结果将是 [2]

在这个例子中,咱们创建了一个既要求数字在指定Range内,又要求是偶数的复合条件。

3. Range与Guava的其他实用工具的结合

Range还可以与Guava中的其他实用工具结合,比如IterablesFluentIterable等,来进行更加复杂的集合操作。

例如,咱们可以结合使用Range和FluentIterable来对集合进行分页处理:

FluentIterable<Integer> fluentNumbers = FluentIterable.from(numbers);
List<Integer> firstPage = fluentNumbers
    .filter(validRange::contains)
    .limit(2)
    .toList();
// 结果将是 [2, 5]

在这个例子中,咱们首先过滤出符合Range条件的元素,然后获取前两个元素作为第一页的内容。

第8章:常见问题与解决方案

1. 范围交叉或重叠的处理

当处理多个范围时,有时会出现交叉或重叠的情况。这可能会导致逻辑上的混乱。比如,两个范围重叠时,如何确定一个值到底属于哪个范围?

解决这个问题的一个方法是使用encloses方法来判断一个范围是否完全包含另一个范围:

Range<Integer> range1 = Range.closed(1, 5);
Range<Integer> range2 = Range.closed(3, 7);
boolean isEnclosed = range1.encloses(range2); // 检查range1是否完全包含range2

如果你需要处理重叠的范围,可以通过intersection方法获取交集,然后根据业务逻辑进行处理。

2. 无效范围或边界条件的处理

有时候,可能会无意中创建了无效的范围,比如上界小于下界的情况。在这种情况下,Range类会抛出异常。

为了避免这种问题,咱们可以在创建Range之前进行检查:

int lowerBound = 5;
int upperBound = 3;
if (lowerBound <= upperBound) {
    Range<Integer> range = Range.closed(lowerBound, upperBound);
} else {
    // 处理无效范围的情况
}
3. 处理边界情况

边界情况,比如范围的最小值或最大值,有时也会造成混淆。明确你的业务逻辑对于边界值的处理方式非常重要。

例如,如果你需要包含边界值,应该使用closed方法。如果不包含边界值,应该使用open或者openClosedclosedOpen等方法。

4. 实际应用案例:数据验证

范围验证是Range常见的一个应用场景。比如,在用户输入验证时,可以使用Range来确保输入的值落在一个合理的范围内:

Range<Integer> ageRange = Range.closed(18, 60);
int userInputAge = 20;
if (ageRange.contains(userInputAge)) {
    // 输入有效
} else {
    // 输入无效,提示用户
}

在这个例子中,咱们使用Range来确保用户的年龄输入在18到60之间。

第9章:Range的实际价值

1. 提高代码的可读性和维护性

首先,使用Range可以大幅提高代码的可读性和维护性。通过声明式的范围表达,代码意图变得更加清晰,也更易于理解和维护。比如:

Range<Integer> scoreRange = Range.closed(0, 100);
// 比起使用 if (score >= 0 && score <= 100) 更易于理解

这样的代码一目了然,告诉我们分数必须在0到100之间。

2. 简化复杂逻辑的处理

Range类在处理涉及范围的复杂逻辑时,可以显著简化代码。在数据分析、校验或处理某些算法时,Range提供了一种直观的方式来表达和操作这些范围。

举个例子,如果咱们需要处理一个复杂的条件,比如一个商品的价格应该在特定的促销范围内,同时还要满足某些其他条件:

Range<BigDecimal> promoPriceRange = Range.closed(new BigDecimal("49.99"), new BigDecimal("199.99"));
List<Product> products = // 获取产品列表
List<Product> promoProducts = products.stream()
    .filter(p -> promoPriceRange.contains(p.getPrice()) && p.isInStock())
    .collect(Collectors.toList());

在这个例子中,Range帮助咱们清晰地定义了促销价格范围,并结合库存状态进行筛选。

3. 跨领域的应用

Range的应用不限于特定领域,它可以跨越多个领域,比如金融、科学计算、数据分析等。在任何需要处理数值范围的地方,Range都能大放异彩。例如,在金融领域,可能需要判断某个交易额是否在允许的范围内:

Range<BigDecimal> transactionRange = Range.closed(new BigDecimal("1000.00"), new BigDecimal("50000.00"));
BigDecimal transactionAmount = // 获取交易额
if (transactionRange.contains(transactionAmount)) {
    // 处理交易
} else {
    // 拒绝交易
}

这样的代码不仅简洁,而且逻辑清晰,易于维护。

结语

本文,咱们一起探索了Guava的Range类的各种强大功能和实际应用。从基本概念到高级技巧,再到实际案例,我希望这些内容能帮助大家更好地理解和使用Range,提高编程效率和代码质量。记住,编程不仅仅是写代码,更是一种艺术。使用像Range这样的工具,可以让我们的编程之路变得更加优雅和高效!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1321355.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis设计与实现之订阅与发布

目录 一、 订阅与发布 1、 频道的订阅与信息发送 2、订阅频道 3、发送信息到频道 4、 退订频道 5、模式的订阅与信息发送 ​编辑 6、 订阅模式 7、 发送信息到模式 8、 退订模式 三、订阅消息断连 1、如果订阅者断开连接了&#xff0c;再次连接会不会丢失之前发布的消…

SiLM5350MDBCA-DG车规级隔离驱动芯片,我们能为汽车智能提供什么?

SiLM5350MDBCA-DG是一款适用于IGBT、MOSFET的单通道 隔离门极驱动器&#xff0c;具有10A拉电流和10A灌电流驱动能 力。提供内部钳位功能&#xff0c;可单独控制 上升时间和下降时间。 在 SOP8 封 装 中 具 有 3000VRMS 隔 离 耐 压 &#xff08; 符 合 UL1577&#xff09;。 与…

MySQL数据库 约束

目录 约束概述 外键约束 添加外键 删除外键 删除/更新行为 约束概述 概念&#xff1a;约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。 目的&#xff1a;保证数据库中数据的正确、有效性和完整性。 分类: 注意&#xff1a;约束是作用于表中字段上…

使用 GBASE南大通用 ADO.NET

GBASE南大通用ADO.NET&#xff08;全称是 .NET Framework Data Provider For GBase&#xff09;提 供给.NET 应用程序访问 GBase 数据库、获取数据、管理数据的一套完整的解决 方案。 GBASE南大通用 ADO.NET 的四个核心类及若干功能类具有以下功能&#xff1a;  建立和管…

喜报|亚数荣获“2023物联网场景应用品牌企业”奖项

12月5日至6日&#xff0c;以“物联中国 数智雄安”为主题的“千企雄安行&#xff1a;2023物联网产业品牌大会”在雄安新区举办。 大会由雄安新区管理委员会、中关村发展集团股份有限公司、物联中国团体组织联席会主办&#xff0c;雄安新区投资促进服务中心、北京物联网智能技术…

layui框架实战案例(25):table组件筛选列记忆功能

即点击当前表格右上角筛选图标后&#xff0c;对表头进行显示隐藏勾选&#xff0c;再刷新页面依然保留当前筛选状态。 要实现layui表格组件的筛选列记忆功能&#xff0c;可以采取以下步骤&#xff1a; 存储筛选数据&#xff1a;当用户进行筛选操作时&#xff0c;将筛选的数据…

leecode-LCR 017. 最小覆盖子串(golang版本)

leecode最小覆盖字串 leecode链接地址 给定两个字符串 s 和 t 。返回 s 中包含 t 的所有字符的最短子字符串。如果 s 中不存在符合条件的子字符串&#xff0c;则返回空字符串 “” 。 如果 s 中存在多个符合条件的子字符串&#xff0c;返回任意一个。 题解 func minWindow(…

电脑屏幕怎么调大小?分享4个实用操作!

“我最近在使用电脑时总感觉电脑屏幕看起来不太对劲&#xff0c;好像字体被刻意放大了&#xff0c;看起来很不舒服&#xff0c;想问问有什么方法可以解决这个问题吗&#xff1f;” 电脑屏幕的正常显示是我们使用电脑的重要前提之一。如果电脑屏幕设置或显示不正确&#xff0c;会…

微信Windows版-无效的WeChatWin.dll文件,错误码126

更新的微信Windows最新版本&#xff0c;突然有一天打开微信提示“无效的WeChatWin.dll文件 错误码 ErrorCode:126,点击“确定”下载最新版本”。 卸载重新安装跟到windows目录下替换WeChatWin.dll皆无效 该解决方案适用于Windows系统&#xff1a;Windows7、Windows10、Windows…

ModuleNotFoundError: No module named ‘openai.error‘

ModuleNotFoundError: No module named ‘openai.error’ result self.fn(*self.args, **self.kwargs) File “H:\chatGPTWeb\chatgpt-on-wechat\channel\chat_channel.py”, line 168, in _handle reply self._generate_reply(context) File “H:\chatGPTWeb\chatgpt-on-wec…

JavaOOP篇----第四篇

系列文章目录 文章目录 系列文章目录前言一、Char类型能不能转成int类型&#xff1f;能不能转化成string类型&#xff0c;能不能转成double类型二、什么是拆装箱&#xff1f;三、Java中的包装类都是那些&#xff1f; 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;…

数据安全传输基础设施平台(二)

5安全传输平台总体设计 5.1 方案特点 规范化&#xff1a;严格遵循各种相关规范设计。独立性&#xff1a;系统各子系统间互相独立&#xff0c;在保持系统间接口的前提下&#xff0c;各系统间的升级互不干扰。最小耦合性&#xff1a;各子系统进行严格功能分解&#xff0c;每个子…

基于云主机的k8s环境搭建

1. 申请三台云主机(按量付费即可) 内网IP配置节点角色172.17.0.92C4Gk8s-master172.17.0.82C2Gk8s-node1172.17.0.172C2Gk8s-node2 2. 安装Kubernetes集群(全部节点执行以下操作) 关闭防火墙 systemctl stop firewalld systemctl disable firewalld关闭selinux sed -i s/e…

Android Studio(3.6.2版本)安装 java2smali 插件,java2smali 插件的使用方法简述

一、Android Studio&#xff08;3.6.2版本&#xff09;安装 java2smali 插件 1、左上角File—>Setting&#xff0c;如下图 2、Setting界面中&#xff1a;点击Plugins—>选择右侧上方Marketplace—>搜索栏输入java2smali&#xff0c;如下图 3、点击Install按钮—>点…

L1-053:电子汪

题目描述 据说汪星人的智商能达到人类 4 岁儿童的水平&#xff0c;更有些聪明汪会做加法计算。比如你在地上放两堆小球&#xff0c;分别有 1 只球和 2 只球&#xff0c;聪明汪就会用“汪&#xff01;汪&#xff01;汪&#xff01;”表示 1 加 2 的结果是 3。 本题要求你为电子宠…

文件拷贝记录丨电脑文件操作拷贝记录监控

最近在我们后台看到了一则这样的咨询&#xff1a; 问我们是否可以查看员工一天做了什么&#xff0c;电脑上打开了什么文件&#xff0c;电脑上的文件操作记录有哪些 叮咚&#xff0c;当然&#xff0c;我们的软件可以实现啦。 具体的操作步骤&#xff0c;我这里演示一下↓ 1、…

基于Java SSM框架实现体育竞赛运动会成绩裁判管系统项目【项目源码+论文说明】

基于java的SSM框架实现体育竞赛运动会成绩裁判管系统演示 摘要 体育竞赛是各种体育体育项目比赛的总称。是在裁判员的主持下&#xff0c;按统一的规则要求&#xff0c;组织与实施的体育员个体或体育队之间的竞技较量&#xff0c;是竞技体育与社会发生关联&#xff0c;并作用于…

Linux中ll -h和du -h 查看的文件大小,同一个文件du -h的结果大很多

当使用 ll -h 和 du -h 查看同一个文件的大小时&#xff0c;可能会看到两者的结果不同&#xff0c;这是因为它们计算文件大小的方式有所不同。 ll -h 的结果&#xff1a; ll -h&#xff08;或其完整形式 ls -lh&#xff09;会显示文件的大小&#xff0c;但这个大小可能只是文件…

JS的浅拷贝和深拷贝

首先理解什么是浅拷贝和深拷贝&#xff1a; 浅拷贝&#xff1a; 浅拷贝只会复制对象的第一层属性&#xff0c;而不会递归地复制嵌套的对象。浅拷贝仅复制对象的引用&#xff0c;新对象和原始对象仍然共享相同的引用&#xff0c;因此对新对象的修改可能会影响到原始对象。浅拷…

聊聊如何实现热插拔AOP

前言 之前偶然看到一篇文章利用aop实现热拔插&#xff08;类似于插件&#xff09;&#xff0c;里面的实现挺好玩。今天我们也来玩一把 前置知识 Advice: org.aopalliance.aop.Advice “通知”&#xff0c;表示 Aspect 在特定的 Join point 采取的操作。包括 “around”, “b…