String的==与equal和null( 转自:http://www.jb51.net/article/18417.htm)

本文详细解析了 Java 中 String 类型的 == 和 equal() 方法的区别,包括它们在不同情况下的行为差异。此外还探讨了 null 值处理及字符串拼接时可能出现的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、String 的==与equal()

在对字符串的相等判断,==判断的是地址是否相同,equal()判断的是字符值是否相同。大多数时候==跟equal()的结果都是相同的。这是因为String对象是不变模式的,如果你不是明确地new一个String对象,Java对于String对象的保存默认的是会把新生成的String 对象放到一个缓冲区,然后每次判断缓冲区中是否已经有了这个对象,如果有了,那么后建立的同样字符值的String对象也会指向最初建立是该字符值对象的地址。也就是说字符值相同的时候,大多数情况下地质也是相同的。==与equal()效果是相同的。但是当对象是str = new String(“abc”)生成的而不是直接str = “abc”这样赋值生成,或者经过了一些字符串连接处理,或者通过StringBuffer等对象生成,都会在内存中开辟新的地址的,这个时候==和 equal()结果是不同的。
是不是稍微有些复杂?这里需要一些关于内存,堆栈,对象保存方面的理解。我不想纠缠于这个问题的讨论。如果不能理解,那么只要记住如果你想要判断两个字符串的字符值是否相等,没有别的要求的时候,那么请使用equal()而不是==,至于什么时候需要使用==,我想当你需要的时候,你自然就会明白了。实际上,对于字符串的判断,我们很少需要用==的。
2、关于str.equal(“abc”)和”abc”.equal(str)
这个好像争论也挺多的,第一种常量写在后面可能符合大多数人的习惯,也符合我们的逻辑思维。但是需要多一个str是否为null的判断。否则这里是有可能出现异常的。而后一种写法不需要多做关于是否为null这个判断。就我个人喜好来说,比较喜欢后一种写法。
3、关于String的null
/**
* 测试java的String为null 的情况
* create date:2009-6-3
* author:Administrator
*
*/
public static void testNull(){
String a= null,b = null,c="呵呵";
System.out.println(a == null);
System.out.println(a+b+c);
}
方法运行结果:
true
nullnull呵呵
所以大家要注意了做字符串合并操作时,别忘记判断null,否则结果会不太让你爽啊!

<think>我们正在处理一个关于高级分页封装的问题,用户引用了优快云文章147954825中的示例代码。由于我们无法直接访问该文章,但根据用户提供的引用资料(引用[1]到[5]),我们可以推断出一些常见的分页封装方法技巧。根据引用资料,分页的基本概念是将大量数据分成多个页面显示,以提高性能用户体验。实现分页通常涉及以下要素:-当前页码-每页记录数-总记录数-总页数-数据列表在高级分页封装中,我们可能还需要考虑:-排序条件-条件查询-分页控件的生成(如前端分页器)-缓存结合参考引用[2][5],我们可以知道分页组件可以在前端(如Vue)或后端(如WinForm)进行封装。引用[3][4]展示了SpringBoot后端分页查询的代码示例。由于用户指定了优快云文章147954825,虽然我们无法获取原文,但我们可以结合常见的分页封装实践,给出一个高级分页封装的示例代码。下面我们将尝试构建一个高级分页封装示例,该示例可能包括:1.一个分页请求参数对象(包含页码、每页大小、排序字段方向等)2.一个分页结果对象(包含总记录数、总页数、当前页数据列表等)3.一个分页工具类,用于执行分页逻辑(可能结合条件查询排序)注意:由于没有具体的文章内容,以下代码为通用高级分页封装示例。###后端分页封装示例(JavaSpringBoot风格)####1.分页请求参数封装类```javapublicclassPageRequest{privateIntegerpage=1;//当前页码,默认为1privateIntegerpageSize=10;//每页记录数,默认为10privateStringsortField;//排序字段privateStringsortDirection;//排序方向,如ASC或DESC//构造方法、gettersetter省略//将当前分页请求换为SpringData的Pageable对象publicPageabletoPageable(){if(sortField!=null&&sortDirection!=null){Sort.Directiondirection=Sort.Direction.fromString(sortDirection);Sortsort=Sort.by(direction,sortField);returnPageRequest.of(page-1,pageSize,sort);//注意:SpringData页码从0开始}else{returnPageRequest.of(page-1,pageSize);}}}```####2.分页结果封装类```javapublicclassPageResult<T>{privatelongtotal;//总记录数privateinttotalPages;//总页数privateintcurrentPage;//当前页码(用户看到的页码,从1开始)privateintpageSize;//每页记录数privateList<T>data;//当前页数据列表//从SpringData的Page对象构造publicPageResult(Page<T>page){this.total=page.getTotalElements();this.totalPages=page.getTotalPages();this.currentPage=page.getNumber()+1;//将Spring的0-based页码换为1-basedthis.pageSize=page.getSize();this.data=page.getContent();}//getter方法省略}```####3.在Service层使用```java@ServicepublicclassUserService{@AutowiredprivateUserRepositoryuserRepository;publicPageResult<User>getUsersByCondition(PageRequestpageRequest,Stringcondition){//将PageRequest换为PageablePageablepageable=pageRequest.toPageable();//根据条件查询(这里假设条件为用户名包含)Page<User>page=userRepository.findByUsernameContaining(condition,pageable);returnnewPageResult<>(page);}}```####4.Controller层```java@RestController@RequestMapping("/users")publicclassUserController{@AutowiredprivateUserServiceuserService;@GetMappingpublicPageResult<User>getUsers(@RequestParam(defaultValue="1")Integerpage,@RequestParam(defaultValue="10")IntegerpageSize,@RequestParam(required=false)StringsortField,@RequestParam(required=false)StringsortDirection,@RequestParam(required=false)Stringcondition){PageRequestpageRequest=newPageRequest();pageRequest.setPage(page);pageRequest.setPageSize(pageSize);pageRequest.setSortField(sortField);pageRequest.setSortDirection(sortDirection);returnuserService.getUsersByCondition(pageRequest,condition);}}```###前端分页封装示例(Vue.js)参考引用[2],我们可以封装一个分页器组件。这里给出一个简化版:```vue<template><divclass="pagination"><button@click="changePage(1)":disabled="currentPage===1">首页</button><button@click="changePage(currentPage-1)":disabled="currentPage===1">上一页</button><spanv-for="pageinpages":key="page"><button@click="changePage(page)":class="{active:currentPage===page}">{{page}}</button></span><button@click="changePage(currentPage+1)":disabled="currentPage===totalPages">下一页</button><button@click="changePage(totalPages)":disabled="currentPage===totalPages">尾页</button></div></template><script>exportdefault{props:{total:Number,//总记录数pageSize:Number,//每页大小currentPage:Number//当前页码},computed:{totalPages(){returnMath.ceil(this.total/this.pageSize);},pages(){//生成页码数组,这里简单返回1到总页数,实际可优化为只显示部分页码constpages=[];for(leti=1;i<=this.totalPages;i++){pages.push(i);}returnpages;}},methods:{changePage(page){if(page>=1&&page<=this.totalPages){this.$emit('page-change',page);}}}}</script>```###高级封装技巧1.**条件查询封装**:可以设计一个通用的条件查询对象,将过滤条件分页排序条件组合在一起。2.**分页缓存**:对于不经常变化的数据,可以将分页结果缓存起来,减少数据库查询(引用[1]中提到)。3.**大数据集优化**:当数据量极大时,可以使用游标分页(基于索引)代替传统的偏移分页,避免深度分页性能问题(引用[1]中提到)。4.**前端分页器优化**:显示页码范围,避免过多页码按钮(如只显示当前页前后几页,加上首尾省略号)。###总结高级分页封装涉及前后端的协作。后端需要提供灵活的分页查询接口,支持条件查询排序;前端则需要一个美观易用的分页器组件。同时,针对性能问题,需要采用合适的策略。由于用户提到的优快云文章147954825的具体内容未知,以上示例为通用高级封装方法。用户可以根据实际需求调整。§§相关问题§§1.如何优化大数据量下的分页查询性能?2.分页查询时如何实现多条件动态过滤?3.前端分页器组件如何实现动态页码显示(如只显示当前页附近的几页)?4.分页查询结果如何缓存结合使用?</think>### 高级分页封装实现方法 在实现高级分页封装时,需要同时考虑**后端分页逻辑****前端分页组件**的协同设计。以下是基于通用实践的高级分页封装方案: #### 一、后端分页封装(Java Spring Boot示例) ```java // 分页请求参数封装类 public class PageParam { private Integer page = 1; // 当前页码 private Integer pageSize = 10; // 每页条数 private String sortField; // 排序字段 private String sortOrder = "ASC"; // 排序方向 // 换为JPA Pageable对象 public Pageable toPageable() { if (sortField != null) { Sort.Direction direction = sortOrder.equalsIgnoreCase("DESC") ? Sort.Direction.DESC : Sort.Direction.ASC; return PageRequest.of(page - 1, pageSize, Sort.by(direction, sortField)); } return PageRequest.of(page - 1, pageSize); } // Getters & Setters } // 分页响应封装类 public class PageResult<T> { private Long total; // 总记录数 private Integer totalPages; // 总页数 private List<T> data; // 当前页数据 // 从Spring Page对象构建 public PageResult(Page<T> page) { this.total = page.getTotalElements(); this.totalPages = page.getTotalPages(); this.data = page.getContent(); } // Getters } // Service层使用示例 @Service public class UserService { @Autowired private UserRepository repository; public PageResult<User> getUsers(PageParam param) { Pageable pageable = param.toPageable(); Page<User> page = repository.findAll(pageable); return new PageResult<>(page); } } ``` #### 二、前端分页组件封装(Vue.js示例) ```vue <template> <div class="pagination"> <button @click="changePage(1)" :disabled="currentPage === 1"> 首页 </button> <button @click="changePage(currentPage - 1)" :disabled="currentPage === 1"> 上一页 </button> <span v-for="page in visiblePages" :key="page"> <button @click="changePage(page)" :class="{ active: currentPage === page }"> {{ page }} </button> </span> <button @click="changePage(currentPage + 1)" :disabled="currentPage === totalPages"> 下一页 </button> <button @click="changePage(totalPages)" :disabled="currentPage === totalPages"> 尾页 </button> <span>每页 <select v-model="pageSize" @change="updatePageSize"> <option v-for="size in [5, 10, 20, 50]" :value="size">{{ size }}</option> </select> 条 </span> </div> </template> <script> export default { props: { total: Number, // 总记录数 currentPage: Number, // 当前页码 pageSize: Number // 每页大小 }, computed: { totalPages() { return Math.ceil(this.total / this.pageSize); }, visiblePages() { // 动态计算显示的页码(显示当前页附近的5个页码) const range = 2; let start = Math.max(1, this.currentPage - range); let end = Math.min(this.totalPages, this.currentPage + range); if (this.currentPage - range <= 1) end = Math.min(5, this.totalPages); if (this.currentPage + range >= this.totalPages) start = Math.max(1, this.totalPages - 4); return Array.from({length: end - start + 1}, (_, i) => start + i); } }, methods: { changePage(page) { if (page >= 1 && page <= this.totalPages) { this.$emit('page-change', page); } }, updatePageSize() { this.$emit('size-change', this.pageSize); } } }; </script> ``` #### 三、高级功能实现技巧 1. **动态查询条件封装** ```java // 增强PageParam类 public class PageParam { // 原有分页参数... private Map<String, Object> filters = new HashMap<>(); // 动态过滤条件 public Specification<T> toSpecification() { return (root, query, cb) -> { List<Predicate> predicates = new ArrayList<>(); filters.forEach((field, value) -> { if (value != null) { predicates.add(cb.equal(root.get(field), value)); } }); return cb.and(predicates.toArray(new Predicate[0])); }; } } // Service层使用 Page<User> page = repository.findAll( param.toSpecification(), param.toPageable() ); ``` 2. **分页缓存优化** ```java @Cacheable(value = "userPage", key = "#param.hashCode()") public PageResult<User> getCachedUsers(PageParam param) { return getUsers(param); } ``` 3. **大数据量分页优化(游标分页)** ```sql /* 使用WHERE id > ? 替代传统LIMIT */ SELECT * FROM users WHERE id > #{lastId} ORDER BY id ASC LIMIT #{pageSize} ``` ### 封装优势分析 1. **前后端解耦**:通过标准化参数(`page`/`pageSize`/`sort`)响应格式(`total`/`data`) 2. **复用性**:封装组件可跨项目复用,减少重复代码 3. **可扩展性**:通过继承可轻松添加特殊分页逻辑 4. **性能优化**:集成缓存、游标分页等高级特性 > **最佳实践建议**:对于超大数据集(>100万),推荐使用**游标分页**代替传统分页,可避免深度分页的性能问题[^1]。同时结合前端的分页组件动态渲染策略,提升用户体验[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值