【JAVA】Collections.sort()实现动态数组自定义排序

Collections.sort()


@SuppressWarnings("unchecked")
    public static <T extends Comparable<? super T>> void sort(List<T> list) {
        list.sort(null);
    }
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static <T> void sort(List<T> list, Comparator<? super T> c) {
        list.sort(c);
    }

Collections.sort()的源码如上所示,可以看到Collections.sort()实现了两种重载

  • 第一种<T extends Comparable<? super T>>:这种方法需要我们实现Comparable接口中的compareTo()方法
  • 第二种对泛型无要求,但是需要我们实现Comparator比较器接口



Comparable排序接口

  • 如果一个类实现了Comparable接口,则该类支持排序
  • 如果一个List或者一个数组中的对象是实现了Comparable接口的类,则可以通过Collections.sort()或者Arrays.sort()来对该数组进行排序

可以通过一个例子来说明。首先我们创建一个类Fruit实现Comparable接口,并且重载compareTo方法

class Fruit implements Comparable<Fruit>{
	private String name;
	private int price;
	
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}


	@Override
	public int compareTo(Fruit f) {
		return this.price-f.price;
	}
	
	@Override
	public String toString() {
		return "the fruit is "+this.name+"\nand the price is "+this.price;
	}	
}
  • 这个类中还重载了toString方法,这样我们可以通过System.out.println(实体对象)直接输出这个对象的信息
  • 本来compareTo()是用于比较字符串的,这里重载之后用于比较int型数字

然后测试一下:

	public static void main(String[] args) {
		List<Fruit> list=new ArrayList<>();
		
		Fruit apple=new Fruit();
		apple.setName("apple");
		apple.setPrice(12);
		
		Fruit banana=new Fruit();
		banana.setName("banana");
		banana.setPrice(7);
		
		list.add(apple);
		list.add(banana);
				
		Collections.sort(list);
		
		System.out.println(list);
	}

运行结果为:
在这里插入图片描述
可以看到,成功通过Collections.sort()对动态数组list中的中的两个对象apple和banana按照价格进行了升序排序

PS:
如果我们需要实现升序排序,重载compareTo()方法时使用【成员变量-方法变量】的方式:

	@Override
	public int compareTo(Fruit f) {
		return this.price-f.price;
	}

如果需要实现降序排序,重载时使用【方法变量-成员变量】的方式:

	@Override
	public int compareTo(Fruit f) {
		return this.price-f.price;
	}



Comparator比较器接口

对刚刚那个例子,这次我们使用Comparator比较器接口来实现Collections.sort()来进行排序:

class Fruit{
	private String price;
	private String name;

	public String getPrice() {
		return price;
	}

	public void setPrice(String price) {
		this.price = price;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "the fruit name is "+name+"\nand the price is "+price;
	}
}

首先可以看到第二种方法中,我们创建的类没有重载compareTo方法。测试方法如下:

	public static void main(String[] args) {
		List<Fruit> list=new ArrayList<>();
		
		Fruit apple=new Fruit();
		apple.setName("apple");
		apple.setPrice("12");
		
		Fruit banana=new Fruit();
		banana.setName("banana");
		banana.setPrice("7");
		
		list.add(apple);
		list.add(banana);
		
		Collections.sort(list,new Comparator<Fruit>() {
			@Override
			public int compare(Fruit f1,Fruit f2) {
				return f1.getPrice().compareTo(f2.getPrice());
			}
		});
				
		System.out.println(list);
	}

运行结果如下:
在这里插入图片描述



拓展一:Comparator比较器接口的另外一种写法

如果一个类对象有多种可以比较的参数,则可以使用自定义比较器来实现对不同参数的排序。
这里同样以刚刚的例子进行说明,令Fuit这个类的成员变量为id、name、price,然后针对Fruit对象的id和price来写自定义比较器来排序。
Fruit类代码如下:

class Fruit{
	private int id;
	private String name;
	private int price;
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}


	@Override
	public String toString() {
		return "id: "+id+"  fruit name: "+name+"  price: "+price;
	}
}
  • 使用自定义比较器接口的话,类就不用实现Comparable接口
  • Fruit的成员变量有id、name、price,每个成员变量都有自己的set和get方法
  • Fruit类重写了toString()方法

对id和price的自定义比较器如下:

	static class PriceComparator implements Comparator<Object>{
		public int compare(Object o1,Object o2) {
			Fruit f1=(Fruit)o1;
			Fruit f2=(Fruit)o2;
			return f1.getPrice()-f2.getPrice();
		}
	}
	
	static class IdComparator implements Comparator<Object>{
		public int compare(Object o1,Object o2) {
			Fruit f1=(Fruit)o1;
			Fruit f2=(Fruit)o2;
			return f1.getId()-f2.getId();
		}
	}
	
	public static void printList(List<Fruit> list) {
		Iterator it=list.iterator();
		while(it.hasNext()) {
			System.out.println(it.next()+"\n");
		}
	}
  • 自定义比较器需要实现Comparator接口,同时实现了该接口中的方法compare()
  • 这里还写了个方法printList,用于打印Fruit数组中的对象

测试方法如下:

public static void main(String[] args) {
		List<Fruit> list=new ArrayList<>();
		
		Fruit apple=new Fruit();
		apple.setId(1);
		apple.setName("apple");
		apple.setPrice(12);
		
		Fruit banana=new Fruit();
		banana.setId(2);
		banana.setName("banana");
		banana.setPrice(7);
		
		list.add(apple);
		list.add(banana);
		
		Collections.sort(list,new PriceComparator());
		System.out.println("按照书的价格来排序"+"\n");
		printList(list);
		
		Collections.sort(list,new IdComparator());
		System.out.println("按照书的ID来排序"+"\n");
		printList(list);
	}

运行结果如下:
在这里插入图片描述



拓展二:使用ES6的语法来写Comparator比较器接口

通过ES6的语法来写的话,代码看起来会简洁很多。例如我们有一个list,list是Fruit对象,现在使用Collections.sort()来对list中的Fruit对象按照id来排序。
首先我们的Fruit的代码为:

class Fruit{
	private int id;
	private String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public String toString() {
		return "id: "+String.valueOf(id)+"\nname: "+name+"\n";
	}
}

然后测试类为:

public class TestComparator{
	public static void main(String[] args) {
		List<Fruit> list=new ArrayList<Fruit>();
		Fruit apple=new Fruit();
		apple.setId(0);
		apple.setName("apple");
		Fruit banana=new Fruit();
		banana.setId(3);
		banana.setName("banana");
		list.add(apple);
		list.add(banana);
		
		Collections.sort(list,(a,b)->(a.getId()-b.getId()));
		
		System.out.println(list);
	}
}

可以发现,Collections.sort()的代码被缩减成了一行:

Collections.sort(list,(a,b)->(a.getId()-b.getId()));
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Arrays.sort()和Collections.sort()都是用于排序的方法,但是有一些区别。 Arrays.sort()是用于对数组进行排序的方法,它使用的是快速排序算法。这意味着它可以对基本类型数组和对象类型数组进行排序。对于基本类型数组,它会使用该类型的比较器进行排序,而对于对象类型数组,则使用对象的自然排序或者自定义的比较器进行排序排序后的结果直接作用于原始数组。 Collections.sort()则是用于对List集合进行排序的方法。它也使用的是快速排序算法,但是它需要传入一个实现了Comparator接口的比较器来进行排序。这意味着它只能对对象类型的集合进行排序,而不能对基本类型的集合进行排序排序后的结果会修改原始集合。 总结来说,Arrays.sort()适用于对数组进行排序,而Collections.sort()适用于对List集合进行排序。它们的主要区别在于排序对象的类型和对原始数据的影响。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [java刷题必备排序,Arrays.sort()和Collections.sort()](https://blog.csdn.net/King_wq_2020/article/details/118911582)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [Arrays.sort()和Collections.sort()的比较](https://blog.csdn.net/carolineme/article/details/118307278)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值