深入解析Guava范围类(Range)

在这里插入图片描述

在这里插入图片描述

第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这样的工具,可以让我们的编程之路变得更加优雅和高效!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python3中_和__的用途和区别

目录 一、_&#xff08;下划线&#xff09; 1、临时变量&#xff1a; 2、未使用的变量&#xff1a; 二、__&#xff08;双下划线&#xff09; 1、私有属性&#xff1a; 2、私有方法&#xff1a; 三、__的一些特殊用途。 总结 Python3中的_和__是两个特殊的标识符&#…

MongoDB的数据库引用

本文主要介绍MongoDB的数据库引用。 目录 MongoDB的数据库引用 MongoDB的数据库引用 MongoDB是一种面向文档的NoSQL数据库&#xff0c;它使用BSON&#xff08;Binary JSON&#xff09;格式存储和查询数据。在MongoDB中&#xff0c;数据库引用是一种特殊的数据类型&#xff0c;…

面试算法56:二叉搜索树中两个节点的值之和

题目 给定一棵二叉搜索树和一个值k&#xff0c;请判断该二叉搜索树中是否存在值之和等于k的两个节点。假设二叉搜索树中节点的值均唯一。例如&#xff0c;在如图8.12所示的二叉搜索树中&#xff0c;存在值之和等于12的两个节点&#xff08;节点5和节点7&#xff09;&#xff0…

本地缓存与多级缓存

一、前言 缓存对于一个高并发场景下的微服务应用来说具有重要的作用&#xff0c;不管是在架构选型还是设计阶段&#xff0c;缓存都是应用扛高并发提升吞吐量的有效手段。缓存对于大多数开发的同学来说并不陌生&#xff0c;一个基本的缓存使用流程如下&#xff1a; 简而言之&am…

华为配置OSPF与BFD联动示例

组网需求 如图1所示&#xff0c;SwitchA、SwitchB和SwitchC之间运行OSPF&#xff0c;SwitchA和SwitchB之间的交换机仅作透传功能。现在需要SwitchA和SwitchB能快速感应它们之间的链路状态&#xff0c;当链路SwitchA-SwitchB发生故障时&#xff0c;业务能快速切换到备份链路Swi…

【LeetCode刷题笔记(9-1)】【Python】【无重复字符的最长子串】【滑动窗口】【中等】

文章目录 引言无重复字符的最长子串题目描述提示 解决方案1&#xff1a;【滑动窗口】结束语 无重复字符的最长子串 引言 编写通过所有测试案例的代码并不简单&#xff0c;通常需要深思熟虑和理性分析。虽然这些代码能够通过所有的测试案例&#xff0c;但如果不了解代码背后的思…

七轴开源协作机械臂myArm视觉跟踪技术!

引言 ArUco标记是一种基于二维码的标记&#xff0c;可以被用于高效的场景识别和位置跟踪。这些标记的简单性和高效性使其成为机器视觉领域的理想选择&#xff0c;特别是在需要实时和高精度跟踪的场景中。结合机器学习和先进的图像处理技术&#xff0c;使用ArUco标记的机械臂系统…

爬虫国密加密案例:某医保服务

声明&#xff1a; 该文章为学习使用&#xff0c;严禁用于商业用途和非法用途&#xff0c;违者后果自负&#xff0c;由此产生的一切后果均与作者无关 一、找出需要加密的参数 js运行 atob(‘aHR0cHM6Ly9mdXd1Lm5oc2EuZ292LmNuL25hdGlvbmFsSGFsbFN0LyMvc2VhcmNoL21lZGljYWw/Y29…

HTML---CSS美化网页元素

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.div 标签&#xff1a; <div>是HTML中的一个常用标签&#xff0c;用于定义HTML文档中的一个区块&#xff08;或一个容器&#xff09;。它可以包含其他HTML元素&#xff0c;如文本、图像…

adb: error: cannot create file/directory ‘d:/1.png‘: No such file or directory

将文件从设备读取到PC 由于权限问题&#xff0c;不能直接pull到电脑磁盘根目录&#xff0c;否则会报错&#xff1a; adb pull <remote> <local> eg: C:\Users\admin>adb pull /sdcard/server.log C:\Users\admin\Desktop /sdcard/server.log: 1 file pulled.…

AI创作系统ChatGPT网站源码,支持AI绘画,支持GPT语音对话+智能思维导图生成

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Ch…

客观题测试-第7章查找

第1关&#xff1a;查找客观题测试&#xff08;一&#xff09; 1、关键字可以唯一地标识一个数据元素。 A、对 B、错 2、二叉排序树是一个动态查找表。 A、对 B、错 3、如果顺序表中各元素的查找概率相同&#xff0c;在顺序查找时&#xff0c;查找不成功的平均查找长度因…

nodejs微信小程序+python+PHP国漫推荐系统-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

TrustZone之其他设备及可信基础系统架构

一、其他设备 最后,我们将查看系统中的其他设备,如下图所示: 我们的示例TrustZone启用的系统包括一些尚未涵盖的设备,但我们需要这些设备来构建一个实际的系统。 • 一次性可编程存储器(OTP)或保险丝 这些是一旦写入就无法更改的存储器。与每个芯片上都包含相同…

【Vue2】Component template should contain exactly one root element.

问题描述 [plugin:vite:vue2] Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.原因分析 这个错误通常是由于 Vue 组件的模板中包含多个根元素导致的。Vue 要求组件模板中只…

图片速览 PoseGPT:基于量化的 3D 人体运动生成和预测(VQVAE)

papercodehttps://arxiv.org/pdf/2210.10542.pdfhttps://europe.naverlabs.com/research/computer-vision/posegpt/ 方法 将动作压缩到离散空间。使用GPT类的模型预测未来动作的离散索引。使用解码器解码动作得到输出。 效果 提出的方法在HumanAct12&#xff08;一个标准但小规…

13.FTP

FTP FTP配置 添加一个本地用户 设置个密码 服务类型是FTP 工作路径授权给用户 设置用户角色为网络管理员 开启FTP服务 R2的路径下有这些文件 在R1进行测试&#xff0c;输入刚才创建的用户密码 get 获取文件 put上传文件 也可以在PC进行访问 可以升级路由器系…

阅览窗格功能虽然便利,但有时会出错,特别是在Word和Excel文件中更为常见

当你打开预览窗格功能时&#xff0c;每次你打开Windows文件资源管理器并选择任何文件&#xff0c;你将在屏幕的右窗格上看到该文件的小预览缩略图。 由于这个新功能&#xff0c;你可以在Windows资源管理器的右窗格上以缩略图的形式看到文件的小预览。此功能在更快地识别文件方…

SVN小白常见操作流程

SVN小白常见操作流程 一、什么是Subversion&#xff1f;二、TortoiseSVN客户端安装教程三、SVN 操作3.1 SVN Ckeckout(检出)3.2 Add(新增文件)3.3 SVN Commit(提交)3.4 SVN Update(更新操作)3.5SVN Delete(删除操作)3.6 SVN Revert to a revision(版本回溯)3.7 不同版本内容之间…

三大主流前端框架介绍

在前端项目中&#xff0c;可以借助某些框架&#xff08;如React、Vue、Angular等&#xff09;来实现组件化开发&#xff0c;使代码更容易复用。此时&#xff0c;一个网页不再是由一个个独立的HTML、CSS和JavaScript文件组成&#xff0c;而是按照组件的思想将网页划分成一个个组…