Java 中数组 binarySearch 方法and拷贝对象工具类CopyUtils-可忽略覆盖Null值详解

简介: [1] 该搜索键在范围内,但不是数组元素,由1开始计数,得“ - 插入点索引值”; [2] 该搜索键在范围内,且是数组元素,由0开始计数,得搜索值的索引值; [3] 该搜索键不在范围内,且小于范围(数组)内元素,返回–(fromIndex + 1); [4] 该搜索键不在范围内,且大于范围(数组)内元素,返回 –(toIndex + 1)。

555555.png

Java中给数组提供了一个二分法查找数组元素的位置,这个方法从JDK1.6开始,很多人不理解,做了一个总结对比看即可。

binarySearch(Object[], Object key)

方法的object[]参数是要查找的数组,key参数为要查找的key值。

方法的返回值有几种:

1.找到的情况下:如果key在数组中,则返回搜索值的索引,从0开始。

2.找不到的情况下:

[1] 搜索值不是数组元素,且在数组范围内,从1开始计数,得“ - 插入点索引值”;

[2] 搜索值是数组元素,从0开始计数,得搜索值的索引值;

[3] 搜索值不是数组元素,且大于数组内元素,索引值为 – (length + 1);

[4] 搜索值不是数组元素,且小于数组内元素,索引值为 – 1。

举例:

int a[] = new int[] { 1, 3, 4, 6, 8, 9 };
        int x1 = Arrays.binarySearch(a, 5);    
        int x2 = Arrays.binarySearch(a, 4);    
        int x3 = Arrays.binarySearch(a, 0);    
        int x4 = Arrays.binarySearch(a, 10);   
        System.out.println("x1:" + x1 + ", x2:" + x2);
        System.out.println("x3:" + x3 + ", x4:" + x4);

打印结果 :

x1:-4, x2:2
x3:-1, x4:-7

binarySearch(Object[], int fromIndex, int toIndex, Object key)

方法的object[]参数是要查找的数组,fromIndex参数是搜索的开始索引(包括),toIndex参数是搜索的结束索引(不包括), key参数为要查找的key值。

方法的返回值有几种:

1.找到的情况下:如果key在数组中,则返回搜索值的索引。

2.找不到的情况下:

[1] 该搜索键在范围内,但不是数组元素,由1开始计数,得“ - 插入点索引值”;

[2] 该搜索键在范围内,且是数组元素,由0开始计数,得搜索值的索引值;

[3] 该搜索键不在范围内,且小于范围(数组)内元素,返回–(fromIndex + 1);

[4] 该搜索键不在范围内,且大于范围(数组)内元素,返回 –(toIndex + 1)。

举例:

int a[] = new int[] { 1, 3, 4, 6, 8, 9 };
        int x1 = Arrays.binarySearch(a, 1, 4, 5);  
        int x2 = Arrays.binarySearch(a, 1, 4, 4);  
        int x3 = Arrays.binarySearch(a, 1, 4, 2);  
        int x4 = Arrays.binarySearch(a, 1, 4, 10);  
        System.out.println("x1:" + x1 + ", x2:" + x2);
        System.out.println("x3:" + x3 + ", x4:" + x4);

打印结果:

x1:-4, x2:2
x3:-2, x4:-5

使用场景:针对两个对象相互拷贝,然后只替换不为Null的值,自带的BeanUtils无法实现,所以单独在网上找了一个然后进行使用,可忽略Null值的拷贝。

最近做一个实训项目,然后持久层使用的JPA,前端使用的Layui,更新的时候如果前端传入了部分字段,那么其他字段没有传入就不做更新,在JPA当中默认传入一个完整的对象,一般都是直接先查询然后再修改这样操作 ,但是前端目前只要求传入什么就修改什么,没有传入的默认不修改,意思就是只修改部分字段内容,所以需要我后端先根据ID查询信息然后再修改就要使用到克隆对象忽略Null值,目前这个工具类就可以实现。

CopyUtils工具类代码:

/**
 * CopyUtils
 *
 * @author lcry
 * @date 2019/09/19 17:31
 * 对象互相拷贝忽略Null值
 */
public class CopyUtils {
    public static String[] getNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
        Set<String> emptyNames = new HashSet<String>();
        for (java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }
    public static void copyProperties(Object src, Object target) {
        BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
    }
}

使用方法非常简单:

/**
     * 修改
     *
     * @param employee
     */
    public void update(Employee employee) {
//        只更新部分字段、2019年9月19日 17:24:11 - 若前端不传入就不更新
        Employee desinfo = employeeDao.findById(employee.getId()).get();
        if (Validator.isNotEmpty(desinfo)) {
            CopyUtils.copyProperties(desinfo, employee);
            employeeDao.save(employee);
        }
    }

可以自行做测试,比BeanUtils中拷贝对象更好使用~

@Test
    public void testcopytest() {
//        初始化第一个对象只设置name
        Employee employee1 = new Employee();
        employee1.setName("Lcry");
//        toString查看对象信息
        System.out.println("初始化employee1->" + employee1);
//        初始化第二个对象,不设置name,设置其他值
        Employee employee2 = new Employee();
        employee2.setAddress("123");
        employee2.setDepid("1");
        employee2.setPassword("123456");
        employee2.setAge(22);
        employee2.setEmail("i@51it.wang");
        System.out.println("初始化employee2->" + employee2);
//        采用CopyUtils只拷贝不为空的属性,name属性为赋值为employee2
        CopyUtils.copyProperties(employee1, employee2);
        System.out.println("通过CopyUtils的employee2->" + employee2);
//        采用自带的BeanUtil只能全部复制、包括Null值
        BeanUtils.copyProperties(employee1,employee2);
        System.out.println("通过BeanUtil的employee2->" + employee2);
    }

打印日志:

初始化employee1->Employee(id=null, name=Lcry, status=null, sex=null, address=null, img=null, phone=null, email=null, password=null, entrytime=null, age=null, empnum=null, title=null, depid=null)
初始化employee2->Employee(id=null, name=null, status=null, sex=null, address=123, img=null, phone=null, email=i@51it.wang, password=123456, entrytime=null, age=22, empnum=null, title=null, depid=1)
通过CopyUtils的employee2->Employee(id=null, name=Lcry, status=null, sex=null, address=123, img=null, phone=null, email=i@51it.wang, password=123456, entrytime=null, age=22, empnum=null, title=null, depid=1)
通过BeanUtil的employee2->Employee(id=null, name=Lcry, status=null, sex=null, address=null, img=null, phone=null, email=null, password=null, entrytime=null, age=null, empnum=null, title=null, depid=null)


目录
相关文章
|
1月前
|
消息中间件 Java Kafka
在Java中实现分布式事务的常用框架和方法
总之,选择合适的分布式事务框架和方法需要综合考虑业务需求、性能、复杂度等因素。不同的框架和方法都有其特点和适用场景,需要根据具体情况进行评估和选择。同时,随着技术的不断发展,分布式事务的解决方案也在不断更新和完善,以更好地满足业务的需求。你还可以进一步深入研究和了解这些框架和方法,以便在实际应用中更好地实现分布式事务管理。
|
1月前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
74 9
|
28天前
|
安全 Java 开发者
Java中WAIT和NOTIFY方法必须在同步块中调用的原因
在Java多线程编程中,`wait()`和`notify()`方法是实现线程间协作的关键。这两个方法必须在同步块或同步方法中调用,这一要求背后有着深刻的原因。本文将深入探讨为什么`wait()`和`notify()`方法必须在同步块中调用,以及这一机制如何确保线程安全和避免死锁。
41 4
|
28天前
|
Java
深入探讨Java中的中断机制:INTERRUPTED和ISINTERRUPTED方法详解
在Java多线程编程中,中断机制是协调线程行为的重要手段。了解和正确使用中断机制对于编写高效、可靠的并发程序至关重要。本文将深入探讨Java中的`Thread.interrupted()`和`Thread.isInterrupted()`方法的区别及其应用场景。
28 4
|
26天前
|
Java 数据处理 数据安全/隐私保护
Java处理数据接口方法
Java处理数据接口方法
26 1
|
1月前
|
安全 Java 编译器
Java对象一定分配在堆上吗?
本文探讨了Java对象的内存分配问题,重点介绍了JVM的逃逸分析技术及其优化策略。逃逸分析能判断对象是否会在作用域外被访问,从而决定对象是否需要分配到堆上。文章详细讲解了栈上分配、标量替换和同步消除三种优化策略,并通过示例代码说明了这些技术的应用场景。
Java对象一定分配在堆上吗?
|
1月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
127 4
|
1月前
|
消息中间件 缓存 Java
java nio,netty,kafka 中经常提到“零拷贝”到底是什么?
零拷贝技术 Zero-Copy 是指计算机执行操作时,可以直接从源(如文件或网络套接字)将数据传输到目标缓冲区, 而不需要 CPU 先将数据从某处内存复制到另一个特定区域,从而减少上下文切换以及 CPU 的拷贝时间。
java nio,netty,kafka 中经常提到“零拷贝”到底是什么?
|
1月前
|
Java 测试技术 Maven
Java一分钟之-PowerMock:静态方法与私有方法测试
通过本文的详细介绍,您可以使用PowerMock轻松地测试Java代码中的静态方法和私有方法。PowerMock通过扩展Mockito,提供了强大的功能,帮助开发者在复杂的测试场景中保持高效和准确的单元测试。希望本文对您的Java单元测试有所帮助。
199 2
|
1月前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第22天】在Java的世界里,对象序列化和反序列化是数据持久化和网络传输的关键技术。本文将带你了解如何在Java中实现对象的序列化与反序列化,并探讨其背后的原理。通过实际代码示例,我们将一步步展示如何将复杂数据结构转换为字节流,以及如何将这些字节流还原为Java对象。文章还将讨论在使用序列化时应注意的安全性问题,以确保你的应用程序既高效又安全。