java排序总结(Comparator、apache-common工具包两种方法)

 在进行java开发时,经常需要对list进行排序,本文对此进行小结。总结了两种方法,第一种是通过原生支持的Comparator做排序,第二种是通过apache-common的工具包进行排序。相比而言,第二种代码可读性、易用性更强,推荐使用第二种。

一、排序目标

我们要对User类组成的list进行排序,先按年龄age倒序排,再按等级grade正序排,如果grade为null,视为最大值,要排在最后。

1.User类

        public class User{
               private int age ;
               private String grade ;
              
               public int getAge() {
                      return age ;
              }
               public void setAge(int age) {
                      this.age = age;
              }
               public String getGrade() {
                      return grade ;
              }
               public void setGrade(String grade) {
                      this.grade = grade;
              }

       }

2.初始化测试数据

User user1 = new User();
user1.setAge(15);
user1.setGrade( "A");
users.add(user1);

User user2 = new User();
user2.setAge(16);
user2.setGrade( "A");
users.add(user2);

User user3 = new User();
user3.setAge(15);
user3.setGrade( null);
users.add(user3);

二、通过Comparator做排序

主要是实现Comparator方法,代码如下
Collections. sort(users, new Comparator<Object>(){

	  @Override
	  public int compare(Object arg1, Object arg2) {
		   User u1 = (User)arg1;
		   User u2 = (User)arg2;
			if(u2.getAge() == u1.getAge())
		   {
				   if(u2.getGrade() == null || u1.getGrade() == null)
				  {
						  if(u2.getGrade() == null)
						 {
								 return -1;
						 }
						  else
						 {
								 return 1;
						 }
				  }
				   return u1.getGrade().compareTo(u2.getGrade());
		   }
			return u2.getAge() - u1.getAge();
	 };

});

代码贴完,再来细说。这段代码实在不忍直视,可读性比较差。首先,为了实现主次排序的需求,需要在if(u2.getAge() == u1.getAge())时,再对grade进行判断,这就多了一层if嵌套。判断grade大小前,还需要对grade是否为null做判断,又多了一个if。其次,再看compare方法的返回值是怎么定义的:如果是正序排序,则当compare方法的参数1(arg1)大于参数2(arg2)时,需返回正数,如果相等,则返回0;逆排则相反,arg1大于arg2时,需返回负数。这个规则不方便记。那么,有没有更好的方法,答案是有的,可以借助apache-common的包。

三、通过apache-common工具包进行排序

1.首先需要引入Apache-common的beanutils、collections、logging三个包


2.代码示例如下

Comparator mycmp1 = ComparableComparator.getInstance ();
mycmp1 = ComparatorUtils. reversedComparator(mycmp1); //逆序

Comparator mycmp2 = ComparableComparator.getInstance ();
mycmp2 = ComparatorUtils. nullHighComparator(mycmp2); //允许null

// 声明要排序的对象的属性,并指明所使用的排序规则,如果不指明,则用默认排序
ArrayList<Object> sortFields = new ArrayList<Object>();
sortFields.add( new BeanComparator("age" , mycmp1)); //主排序(第一排序)
sortFields.add( new BeanComparator("grade" , mycmp2)); //次排序(第二排序)

// 创建一个排序链
ComparatorChain multiSort = new ComparatorChain(sortFields);

// 开始真正的排序,按照先主,后副的规则
Collections.sort (users , multiSort);

3.说明

其实大家看代码应该就能明白了,这里再啰嗦几句,看工具包是如何减轻程序员压力的
首先,通过ComparatorUtils封装好的排序器,可以直接声明是要倒序排,还是正序排(默认是正序,不需要声明),而不需再考虑Comparator返回值。
其次,通过ComparatorChain排序链的先后添加顺序,可以很方便地定义第一排序、第二排序甚至是第九百九十九排序……
最后,通过BeanComparator,直接传参为要排序的字段名称,代码可读性很强,之后要替换也很方便。假设要将age替换成别的排序字段,在第一种排序方法中,至少要替换四个地方,而在这里,替换一个地方即可。

### Java 中用于比较文件内容的第三方库 在 Java 生态系统中,存在多个高效的第三方库可以用来比较文件的内容。以下是几个常用的选项: #### Apache Commons IO Apache Commons IO 是一个非常流行的工具包,提供了丰富的 I/O 操作功能,其中包括文件对比的功能。 ```java import org.apache.commons.io.FileUtils; import java.io.File; public class FileComparator { public static void main(String[] args) throws Exception { File file1 = new File("path/to/file1.txt"); File file2 = new File("path/to/file2.txt"); boolean filesAreEqual = FileUtils.contentEquals(file1, file2); System.out.println("Files are equal: " + filesAreEqual); } } ``` 此方法会逐字节读取两个文件并进行比较[^3]。 #### Google Guava Libraries Google 开发的 Guava 库也提供了一种简单的方式来实现文件内容的比较操作。 ```java import com.google.common.io.Files; import java.nio.charset.StandardCharsets; import java.io.File; public class FileComparatorGuava { public static void main(String[] args) throws Exception { File fileA = new File("filea.txt"); File fileB = new File("fileb.txt"); boolean contentMatch = Files.equal(fileA, fileB); System.out.printf("Content matches? %s%n", contentMatch); String diff = Files.asCharSource(fileA, StandardCharsets.UTF_8).read() + "<=>" + Files.asCharSource(fileB, StandardCharsets.UTF_8).read(); System.out.print(diff); } } ``` 这段代码不仅能够判断两份文档是否相同,还可以打印出它们的具体差异[^4]。 对于更复杂的场景,比如忽略空白字符或只关注特定部分的变化,则可能需要考虑其他专门设计来处理这些需求的专业级解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值