`
言日星极
  • 浏览: 24040 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

使用二分法查找java对象

阅读更多
        在J2EE Web项目开发中,Excel导入导出批量处理数据是比较常见的。在Excel导入时涉及到业务逻辑之类的校验。譬如说:导入的数据是否存在于数据库中,否做添加数据操作,是则作更新操作,大部分系统不只是单纯的更新数据,根据某些业务规则来确认是否更新数据,需要取到要更新的数据。而这个时候如果要遍历导入的数据集合,去数据库查询并取到与之相关的持久化数据,最终根据相关业务逻辑进行再一步操作。当然了像这种方式,如果要导入的数据有两三千条,那岂不是最少也要查询两三千次数据库?如果还有其他业务也需要查询数据库那么与数据库的交互就更频繁了,所以这种做法一般情况下不是太合理的,我们在实际开发中应该尽可能的减少和数据库的交互,以达到性能要求。
        我们可以从数据库中查询出相应的要更新的数据集合,这里我们叫它持久化数据集合,如果说要查找出与导入的数据集合中相应的数据,使用双重循环也是不错的选择。先循环导入的数据集合,然后拿当前遍历到的数据再来一个循环去持久化数据集合中查找对应的对象。但是一般建议不这样做,使用二分法(折半查找)替代双重循环要好的多。下面一个小demo演示了如何使用二分法在集合中查找相应的对象。

public class User implements Comparable<User>, Serializable{	
	private static final long serialVersionUID = -5410921420480739669L;
	private String name;				// 姓名
	private String nationalIdentifier;	// 身份证号码
	/**
	 * 实现Comparable接口的compareTo方法,该方法表示传入的对象与当前对象谁大谁小
	 * 传入的参数对象u的属性nationalIdentifier大于当前对象的natioanlIdentifier返回正数
	 * 否则返回负数,相等返回0(有兴趣的朋友可以查看String类的源码)
	 * 使用二分法在集合中查询某个元素的前提是该集合已经排序好了,如果要查找的元素是自定义类,则必须实现Comparable接口并实现compareTo接口
	 */
	@Override
	public int compareTo(User u) {
		if(u != null)
			// 调用了String类的compareTo方法
			return this.nationalIdentifier.compareTo(u.nationalIdentifier);
		return -1;
	}
	/**
	 * 重写Object类的equals方法
	 * 在这里两个User对象的姓名和身份证号码相等表示这两个User对象相等
	 */
	@Override
	public boolean equals(Object obj){
		User u = (User) obj;
		if(
			this.name.equals(u.name) 
				&& 
			this.nationalIdentifier.equals(u.nationalIdentifier)
			) {
			return Boolean.TRUE;
		}
		return Boolean.FALSE;
	}
	public User(String _name, String _nationalIdentifier){
		this.name = _name;
		this.nationalIdentifier = _nationalIdentifier;
	}
	// ... 其他代码
}


public class Application{
	
	public static void main(String[] args) {
		// 假设这里的iList是要导入的Excel数据集合 iList = import list
		List<User> iList = new ArrayList<User>(2);
		iList.add(new User("学点啥小许", "www.xuediansha.com/city.php?ename=shenzhen"));
		iList.add(new User("学点啥小周", "www.xuediansha.com/city.php?ename=guangzhou"));
		// 这里假设pList是从数据库中查询的持久化集合 pList = persistent list
		List<User> pList = new ArrayList<User>(6);
		pList.add(new User("学点啥老武", "www.xuediansha.com/city.php?ename=xian"));
		pList.add(new User("学点啥老周", "www.xuediansha.com/city.php?ename=beijing"));
		pList.add(new User("学点啥老许", "www.xuediansha.com/city.php?ename=shanghai"));
		pList.add(new User("学点啥小许", "www.xuediansha.com/city.php?ename=shenzhen"));
		// 在使用二分法在集合中查找某个元素需要将该集合进行排序,使用Collections工具类的sort方法即可
		Collections.sort(pList);
		// cUser = current user
		User cUser;
		// eUser = each User
		for(User eUser : iList) {
			cUser = binarySearch(pList, eUser);
			if(cUser != null) {
				System.out.println(cUser.getName());
				// ... 其他操作
			}
		}
	}
	/**
	 * 使用二分法在list集合中查找user对象
	 * @param list 传入的持久化数据集合
	 * @param user 要查询的对象
	 * @return
	 */
	public static User binarySearch(List<User> list, User user) {
		// curPos = current position
		int curPos;
		// startPos = start position
		int startPos = 0;
		// endPos = end position
		int endPos = list.size() - 1;
		// cUser = current user
		User cUser;
		int counts = 0;
		while(true) {
			// curPos = current position
			curPos = (startPos + endPos) / 2;
			cUser = list.get(curPos);
			if(user.equals(cUser)) {
				System.out.printf("查找了%d次\n", counts);
				return cUser;
			} else if (endPos < startPos) {
				return (cUser = null);
			} else {
				if(user.compareTo(cUser) > 0) {
					startPos = curPos + 1;
				} else {
					endPos = curPos - 1;
				}
			}
			counts++;
		}
	}
}


当然了,执行这样的批量更新操作,在将持久化数据查询出来的同时最好锁定这些数据,至于使用何种锁机制,根据不同系统业务来做决定(悲观锁/乐观锁)。
分享到:
评论

相关推荐

    二分法 文件写入读出

    对于文件读出,我们可以先读取文件中的所有数据到内存,比如一个ArrayList,然后使用二分法查找特定值。这样可以快速定位到目标数据,提高效率。 在Java中,生成随机数可使用`java.util.Random`类。例如,我们可以...

    21天学会Java之(Java SE第八篇):数组、冒泡排序法、二分法查找

    数组 数组的定义 数组是相同类型数据的有序集合,数组描述的是相同类型...数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中存储的。 数组声明 在声明数组变量

    java算法——插补查找法

    插补查找法 * 其原理与二分法查找是相同的,搜寻的对象大于500时, * 比二分法查找速度快 * (K-K1)/(Ku-K1)=(m-1)/(u-1)

    Java程序设计基础:一维数组应用查找线性查找).pptx

    二分法查找 数组的查找——线性查找 也称顺序查找法,基本思想: 11 22 43 90 4 90 56 49 -10 3 0 1 2 3 4 5 6 7 8 9 将要查找的对象(关键字key)与数组中每个元素逐一比较,如果某一元素值与关键词key相等,则表示...

    java数组与简单排序

    Java作为一种广泛使用的面向对象的编程语言,提供了丰富的数组操作支持。本主题将深入探讨“java数组与简单排序”,涵盖有序数组、线性查找和二分法查找等核心概念。 有序数组是指数组中的元素按照特定顺序排列,...

    java数据结构测试题及答案解析.doc

    - 二分法查找是一种在有序数组中查找特定元素的算法,它通过不断将查找区间折半来缩小搜索范围,提高查找效率。适用于顺序存储的有序线性表,不适用于链表。 2. **过程设计工具**: - PDL(过程设计语言)、PAD图...

    达内JAVA培训综合笔记

    同时,也介绍了两种常见的排序算法——插入排序和冒泡排序,以及二分法查找。这部分最后提及了Java系统API方法的调用、二进制基础和Java基础其他注意事项。 三、面向对象 面向对象是Java编程的核心思想,笔记中对类...

    各种经典算法实,程式练习题

    Java则提供了丰富的类库和面向对象特性,易于编写和维护大规模项目。在实际编程中,可以根据需求选择合适的语言。 总结,这个压缩包包含的经典算法练习题目,旨在提升程序员的逻辑思维能力和编程技巧。通过学习和...

    联想最新秋招java笔试题目.docx

    * 顺序表的二分法查找需要比较次数为 log2(n+1),其中 n 是顺序表的长度。 二、算法 * 二分法查找是查找算法中的一种,时间复杂度为 O(log n)。 * 在顺序表中,用二分法查找关键码值 11,所需的关键码比较次数为 4...

    2022年最全的java学习笔记必看.docx

    二分法查找是一种常用的查找算法,通过比较和跳过元素来查找数据。 2.14 Java系统API措施调用 Java系统API措施调用是指Java语言中的系统API调用,包括Math类、String类、Array类等。 2.15 二进制基础 二进制基础是...

    JAVA泛型简单排序实例

    JAVA泛型源代码实现以下功能:返回数组元素的最大值/最小值下标;判断数组元素是否按升序排列;T对象数组排序;二分法查找key元素;

    全国计算机二级java习题集

    - 子类对象可以作为父类对象使用,这是因为子类继承了父类的所有公开和受保护的属性(除了private)。 - Java运行时会根据对象的实际类型来决定调用哪个方法。 #### 六、自定义表格类的Model部分 **题目描述:** ...

    java 讲师笔记

    2.13 二分法查找:二分查找是一种在有序数组中查找特定元素的高效算法。 2.14 Java系统API方法调用:Java系统API提供了大量的类和方法供开发者使用。 2.15 二进制基础:了解二进制是理解和编写计算机程序的基础。 ...

    java学习笔记

    6. 排序与查找:包括插入排序、冒泡排序、二分法查找等基本算法。 7. Java系统API方法调用:Java自带的一些系统API方法调用方式。 8. 二进制基础:Java中的二进制知识和运算。 9. 面向对象:封装、继承、多态等面向...

    java私塾学习笔记整理

    **三、二分法查找** 二分查找法是在有序数组中查找特定元素的高效算法,时间复杂度为O(log n)。 #### 第六章:常见类的使用 **一、Object类** Object类是所有Java类的基类,包含一些基本方法如`equals()`、`...

    最全的java学习笔记(必看).pdf

    此外,二分法查找是一种高效的搜索算法,适用于已排序的列表,通过不断缩小查找范围找到目标值。 【Java系统API方法调用】 Java标准库提供了大量预定义的类和方法,这些API可以帮助开发者实现各种功能,如文件操作...

    最全的java学习笔记(必看).docx

    二分法查找是一种在有序数组中查找特定元素的高效算法,它的复杂度为O(log n)。 【系统API方法调用】 Java标准库提供了丰富的API,涵盖了输入输出、网络通信、集合框架等多个方面。熟练掌握并利用这些API可以大大...

    Java面试指南2016

    在数据结构与算法部分,书中提到了常见的排序算法和搜索算法,如冒泡排序、选择排序、插入排序、快速排序、二分法查找等。这些算法是解决实际编程问题的基础,也是许多算法面试题目的核心。求职者需要对这些基础算法...

    数据结构(Java版)第四版 叶核亚编著,习题解答

    文件`08.2 二分法查找 【习题解答8-9】`可能包含如何在有序数组中使用二分查找法查找特定元素的示例。 8. **二叉排序树**:二叉排序树是二叉树的一种,它的左子树只包含小于根节点的元素,右子树只包含大于根节点的...

Global site tag (gtag.js) - Google Analytics