java中的compareto方法的详细介绍

Java Comparator接口实例讲解(抽象方法、常用静态/默认方法)

一.java中的compareto方法

1.返回参与比较的前后两个字符串的asc码的差值,如果两个字符串首字母不同,则该方法返回首字母的asc码的差值

     String a1 = "a";
String a2 = "c";
System.out.println(a1.compareTo(a2));//结果为-2

 

2.即参与比较的两个字符串如果首字符相同,则比较下一个字符,直到有不同的为止,返回该不同的字符的asc码差值,

     String a1 = "aa";
String a2 = "ad";
System.out.println(a1.compareTo(a2));//结果为-3

3.如果两个字符串不一样长,可以参与比较的字符又完全一样,则返回两个字符串的长度差值

     String a1 = "aa";
String a2 = "aa12345678";
System.out.println(a1.compareTo(a2));//结果为-8

4.返回为正数表示a1>a2, 返回为负数表示a1<a2, 返回为0表示a1==a2;

5.数字类型不能用compareTo,nt跟int的比较不能用compareTo方法,直接用大于(>) 小于(<) 或者 等于(==) 不等于(!=)来比较即可

    int num1 = 4;
int num2 = 5;
num1.compareTo(num2);//Cannot invoke compareTo(int) on the primitive type int 

你可以先把你的int型变量转换成String再进行比较

     int num1 = 4;
int num2 = 5; //parse int to String
System.out.println((num1+"").compareTo(num2+""));//-1
System.out.println(new Integer(num1).toString(). compareTo(new Integer(num2).toString()));//-1
System.out.println(String.valueOf(num1).compareTo(String.valueOf(num2)));//-1

6.compareToIgnoreCase忽略大小写

不考虑大小写,按字典顺序比较两个字符串。此方法返回一个整数,它的正负号是调用 compareTo 的正负号,调用时使用了字符串的规范化版本,其大小写差异已通过对每个字符调用 Character.toLowerCase(Character.toUpperCase(character)) 得以消除。
注意,此方法不 考虑语言环境,因此可能在某些特定的语言环境中产生不理想的排序。java.text 包提供 Collators 来完成语言环境敏感的排序。

7.int型可以直接比较,所以没有用到compareTo比较,如果声明的是Date、String、Integer、或者其他的,可以直接使用compareTo比较,

      Integer n1 = 5;
Integer n2 = 6;
System.out.println(n1.compareTo(n2));//-1

二. Comparable<T>接口中的compareTo

 compareTo方法内必须做非空判断(规范问题),当然int类型就不用了。

  注意事项:

    1、模型必须实现Comparable<T>接口

    2、Collection.sort(list)会自动调用compareTo,如果没有这句,list是不会排序的,也不会调用compareTo方法

    3、如果是数组则用Arrays.sort(a)方法

注意要非空判断,这里实例就不判断了

  private int bookId;

    private String bookName;

    private int bookPrice;

    @Override
public int compareTo(Book o) {
// TODO Auto-generated method stub //return this.bookPrice-o.bookPrice;//按价格排序 升序
//return o.bookPrice-this.bookPrice;//按价格排序 降序 //return this.bookName.compareTo(o.bookName);//按书名排序 升序 //先按 id 再按价格 最后按书名排序 升序
int result = this.bookId - o.bookId;
if(result == 0){
result =this.bookPrice - o.bookPrice;
}
if(result == 0){
result = this.bookName.compareTo(o.bookName);
}
return result; }
package com.my.test.compare;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List; public class TestCompare {
public static void main(String[] args) {
Book b1 = new Book(1, "语文", 20);
Book b2 = new Book(2, "数学", 10);
Book b3 = new Book(5, "英语", 10);
Book b4 = new Book(4, "化学", 50);
Book b5 = new Book(3, "化学", 10);
//Book b6 = null;//不能为null,Collections.sort调用compareTo会报空指针异常 List<Book> books = new ArrayList<>();
books.add(b1);
books.add(b2);
books.add(b3);
books.add(b4);
books.add(b5);
System.out.println("Collections 排序前"); for (Book book : books) {
System.out.println(book); }
Collections.sort(books);
System.out.println("Collections 排序后"); for (Book book : books) {
System.out.println(book); } Book[] b = new Book[5];
System.out.println(b.length); b[0] = b1;
b[1] = b2;
b[2] = b3;
b[3] = b4;
b[4] = b5; System.out.println("Arrays 排序前" );
for (Book book : b) {
System.out.println(book);
} Arrays.sort(b); System.out.println("Arrays 排序后" );
for (Book book : b) {
System.out.println(book);
} } }

在应用中我们为了好判断状态,一般处理为

    if(this.bookId<o.bookId){
return -1;
}else if(this.bookId>o.bookId){
return 1;
}else{
return 0;
}

返回值为 1,0.-1:

三。 Comparator接口

源码:

@FunctionalInterface
public interface Comparator<T> {
// 核心方法,用来比较两个对象,如果o1小于o2,返回负数;等于o2,返回0;大于o2返回正数
int compare(T o1, T o2);
// 好像很少用到,一般都用对象自带的equals
boolean equals(Object obj); /**-----------下面的都是JDK1.8新增的接口,挑几个放进去----------*/ //返回反向排序比较器
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
//根据名字知道,先进行compare比较后,再进行一次比较
default Comparator<T> thenComparing(Comparator<? super T> other) {
Objects.requireNonNull(other);
return (Comparator<T> & Serializable) (c1, c2) -> {
int res = compare(c1, c2);
return (res != 0) ? res : other.compare(c1, c2);
};
}
//对int类型的key进行比较
public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
}
//返回正常顺序的比较器
public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
}
}

一起来看一下如何使用,先来看一下JDK1.8以前的用法:

Collections.sort(books,new Comparator<Book>() {

            @Override
public int compare(Book o1, Book o2) {
// TODO Auto-generated method stub return o1.getBookPrice() - o2.getBookPrice(); }
});

或者创建一个比较器

package com.my.test.compare;

import java.util.Comparator;

public class SimpleCompator implements Comparator<Book> {

    @Override
public int compare(Book o1, Book o2) {
// TODO Auto-generated method stub
return o1.getBookPrice() -o2.getBookPrice();
} }
Collections.sort(books,new SimpleCompator());

JDK1.8以前的用法要自己手动实现Comparator接口,然后调用Collections.sort(),传入实现类来完成排序,非常麻烦,而JDK1.8则相对来说简单了很多:

        Collections.sort(books,(Book a, Book b) -> { return a.getBookPrice()-b.getBookPrice(); });

或者可以简单的写为

        Collections.sort(books,(Book a, Book b) ->  a.getBookPrice()-b.getBookPrice());

甚至,我们可以不使用Collections.sort:

books.sort((Book a, Book b) -> a.getBookPrice()-b.getBookPrice() );

详见:http://www.manongjc.com/article/8005.html

compator 在 treeMap 中的 应用(基于key的排序):

treeMap默认的是基于key的从小到大 的排列

自定义排序也是基于key的,如果key object类型 可以自定义各种排序

            TreeMap<String, Person> treeMap = new TreeMap<>((String a,String b)-> b.compareTo(a));//降序
            TreeMap<String, Person> treeMap = new TreeMap<>((String a,String b)-> a.compareTo(b));//升序

TreeMap的按value排序(转换成entry list 然后排序)汉字是按ascii码排序的,不是汉语拼音

Person p1 = new Person(1, "A小红");
Person p2 = new Person(5, "D赵明");
Person p3 = new Person(2, "W孙宇");
Person p4 = new Person(9, "C黎明"); TreeMap<String, Person> treeMap = new TreeMap<>(); treeMap.put("45", p1);
treeMap.put("12", p2);
treeMap.put("85", p3);
treeMap.put("33", p4); List<Map.Entry<String, Person>> entries = new ArrayList<>(treeMap.entrySet()); Collections.sort(entries,
(Map.Entry<String, Person> e1, Map.Entry<String, Person> e2) -> ((Person) e1.getValue()).getPersonName()
.compareTo(((Person) e2.getValue()).getPersonName()));
System.out.println("按名字顺序排列");
for (Entry<String, Person> entry : entries) {
System.out.println(entry.getValue()); }

java中的compareto方法的详细介绍的更多相关文章

  1. java中的compareto方法以及LIst列表排序的详细介绍【转】

    java中的compareto方法的详细介绍 javacompareTo  java中的compareto方法,返回参与比较的前后两个字符串的asc码的差值,看下面一组代码 String a=&quo ...

  2. 转载:Java中的字符串常量池详细介绍

    引用自:http://blog.csdn.net/langhong8/article/details/50938041 这篇文章主要介绍了Java中的字符串常量池详细介绍,JVM为了减少字符串对象的重 ...

  3. Java中的compareTo()方法,compareToIgnoreCase()方法

    1.compareTo(String)方法: Java中String类有一个compareTo方法,该方法返回一个int类型的数据.其比较规则是:拿出字符串的第一个字符与参数的第一个字符进行比较,如果 ...

  4. Java——String类中的compareTo方法总结

    String类的定义:    java.lang  类 String   java.lang.Object      java.lang.String 所有已实现的接口:Serializable, C ...

  5. Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例

    概要  前面,我们已经学习了ArrayList,并了解了fail-fast机制.这一章我们接着学习List的实现类——LinkedList.和学习ArrayList一样,接下来呢,我们先对Linked ...

  6. Java 集合系列10之 HashMap详细介绍(源码解析)和使用示例

    概要 这一章,我们对HashMap进行学习.我们先对HashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用HashMap.内容包括:第1部分 HashMap介绍第2部分 HashMa ...

  7. Java 集合系列11之 Hashtable详细介绍(源码解析)和使用示例

    概要 前一章,我们学习了HashMap.这一章,我们对Hashtable进行学习.我们先对Hashtable有个整体认识,然后再学习它的源码,最后再通过实例来学会使用Hashtable.第1部分 Ha ...

  8. 【转】Java 集合系列11之 Hashtable详细介绍(源码解析)和使用示例

    概要 前一章,我们学习了HashMap.这一章,我们对Hashtable进行学习.我们先对Hashtable有个整体认识,然后再学习它的源码,最后再通过实例来学会使用Hashtable.第1部分 Ha ...

  9. Java中的三大特性 - 超详细篇

    前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的三大特性 - 超详细篇>,希望对大家有帮助,谢谢 这一节的内容可能有点多,大家可以选择性的来看 简介 Java的三大特性:封装.继 ...

随机推荐

  1. 理解MVC/MVP/MVVM的区别

    转载至[http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html] MVC 所有的通信都是单向的. M(Model)V(View)C(Contro ...

  2. LC 759. Employee Free Time 【lock, hard】

    We are given a list schedule of employees, which represents the working time for each employee. Each ...

  3. OpenStack 对接 Ceph 环境可以创建卷但不能挂载卷的问题

    问题 环境:Nova.Cinder.Glance 都对接了 Ceph RBD 后端存储. 以往的操作包括上传镜像.创建卷.挂载卷都是一切正常的,但突然出现了无法挂载卷的问题,而且还是因为 Ceph 客 ...

  4. 小D课堂 - 新版本微服务springcloud+Docker教程_汇总

    小D课堂 - 新版本微服务springcloud+Docker教程_1_01课程简介 小D课堂 - 新版本微服务springcloud+Docker教程_1_02技术选型 小D课堂 - 新版本微服务s ...

  5. 转:async异步、thread多线程

    很全面的知识,转来留着 1:https://www.cnblogs.com/xibei/p/11826498.html 2:https://www.cnblogs.com/xibei/p/118742 ...

  6. golang depth read map

    Foreword: I optimized and improved the below solution, and released it as a library here: github.com ...

  7. 【ABAP系列】SAP ABAP如何在调试查看EXPORT/IMPORT 内存数据

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP如何在调试查看E ...

  8. Python-数据库连表查询、子查询

    连表查询 [实例]通过例子来熟悉连表查询的概念 # 第一步:建表 # 建立英雄职业分类表格 create table classification( id int, name varchar(20) ...

  9. UOJ#495晒被子

    #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #inc ...

  10. 蒲公英v5p%n搭建局域网后用nginx做代理的配置

    1.nginx.conf worker_processes auto; error_log /usr/local/var/log/nginx/error.log; events { worker_co ...