ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

转:Guava Ordering的使用

2020-10-10 13:31:35  阅读:241  来源: 互联网

标签:info 排序 log Ordering list 使用 Guava public


参考

官方说明文档-OrderingExplained 
Guava强大的”流畅风格比较器”-翻译版 
Guava —- Ordering排序工具-简单的使用 
Guava学习笔记:Ordering犀利的比较器

概述

排序器Ordering是Guava流畅风格比较器Comparator的实现,它可以用来为构建复杂的比较器,以完成集合排序的功能。 
从实现上说,Ordering实例就是一个特殊的Comparator实例。Ordering把很多基于Comparator的静态方法(如Collections.max)包装为自己的实例方法(非静态方法),并且提供了链式调用方法,来定制和增强现有的比较器。

简单使用

创建方式

Ordering.natural()

对可排序类型做自然排序,如数字按大小,日期按先后排序

List<Integer> list = Arrays.asList(1, 5, 3, 8, 2);
Collections.sort(list, Ordering.natural());

Ordering.usingToString

按对象的字符串形式做字典排序

List<String> listString = Lists.newArrayList("wang", "test", "a");
Collections.sort(listString, Ordering.usingToString());

Ordering.from(Comparator)

使预先存在的比较器进行排序

List<Worker> workers = Lists.newArrayList(worker, worker2, worker22, worker3);
Ordering<Worker> orderWorker = Ordering.from(new WorkerIdComparator());
Collections.sort(workers, orderWorker);

链式调用方法:通过链式调用,可以由给定的排序器衍生出其它排序器

reverse

获取语义相反的排序器

@Test
public void testOrderReverse() {
    List<Integer> list = Arrays.asList(1, 5, 3, 8, 2);
    Collections.sort(list, Ordering.natural().reverse());
    log.info("获取最大的元素" + Ordering.natural().max(list).toString());
    log.info("排序后" + list.toString());
}

nullsFirst nullsLast

使用当前排序器,但额外把null值排到最前面,最后,原生的JDKCollections.sort会出现异常的,如果排序元素为空

原生调用
/**
 * 排序中出现,空指针会异常的!
 */
@Test(expected = NullPointerException.class)
public void testJDKOrderIssue() {
  List<Integer> list = Arrays.asList(1, 5, null, 3, 8, 2);
  log.info("排序前" + list.toString());
  Collections.sort(list); // 出现异常...
}
使用Guava Ordering
/**
 * 将空值放置在最前面的情况
 */
@Test
public void testOrderNaturalByNullFirst() {
    List<Integer> list = Arrays.asList(1, 5, null, 3, 8, 2);
    Collections.sort(list, Ordering.natural().nullsFirst());
    log.info("空在最前面-排序后" + list.toString());
}

多字段排序 compound(Comparator)

合成另一个比较器,以处理当前排序器中的相等情况。

public class WorkerIdComparator implements Comparator<Worker> {
    @Override
    public int compare(Worker worker1, Worker worker2) {
        return Ints.compare(worker1.getWorkId(), worker2.getWorkId());
    }
}

public class WorkerNameComparator implements Comparator<Worker> {
    @Override
    public int compare(Worker worker1, Worker worker2) {
        return worker1.getName().compareTo(worker2.getName());
    }
}


/**
 * http://blog.csdn.net/wenniuwuren/article/details/46361119
 * guava 多参数排序
 * http://ifeve.com/google-guava-ordering/
 * Ordering.from 的使用
 */
@Test
public void testFrom() {
    Worker worker = new Worker(1, "wangji");
    Worker worker2 = new Worker(11, "guava");
    Worker worker22 = new Worker(11, "aaa");
    Worker worker3 = new Worker(111, "wangji3");
    List<Worker> workers = Lists.newArrayList(worker, worker2, worker22, worker3);
    Ordering<Worker> orderWorker = Ordering.from(new WorkerIdComparator());
    Collections.sort(workers, orderWorker);
    log.info("单参数:" + workers.toString());

    // compound 相等的情况下,考虑第二个参数进行比较
    Ordering<Worker> orderManyWorker = Ordering.from(new WorkerIdComparator()).compound(new WorkerNameComparator()).reverse();
    Collections.sort(workers, orderManyWorker);
    log.info("多参数:" + workers.toString());

}

运用排序器:Guava的排序器实现有若干操纵集合或元素值的方法

isOrdered

判断可迭代对象是否已按排序器排序:允许有排序值相等的元素。

/**
 * isOrdered(Iterable)  判断可迭代对象是否已按排序器排序:允许有排序值相等的元素。
 */
@Test
public void testOrderNatural() {
    List<Integer> list = Arrays.asList(1, 5, 3, 8, 2);
    Collections.sort(list);
    boolean order = Ordering.natural().isOrdered(list); //是否为按照这样的顺序排好序的!自然的排序
    log.info("排好序的:" + (order == true ? "是的" : "不是"));
}

min(E, E),min(E, E, E, E…),min(Iterable)

返回两个参数中最小的那个。如果相等,则返回第一个参数。 
返回多个参数中最小的那个。如果有超过一个参数都最小,则返回第一个最小的参数 
返回迭代器中最小的元素。如果可迭代对象中没有元素,则抛出NoSuchElementException。 
max同理,这样的操作节省了一点时间和精力

/**
 * 返回元素中的最大的值,同理最小的
 */
@Test
public void testMax() {
    List<Integer> list = Arrays.asList(1, 5, 3, 8, 2);
    log.info("获取最大的元素" + Ordering.natural().max(list).toString()); //获取最大的元素8

    log.info("获取最大的元素" + Ordering.natural().reverse().max(list).toString());//获取最大的元素1
}

greatestOf

获取可迭代对象中最大的k个元素,简化我们的操作的工作量

/**
 * 返回一个排序对象中的最大的多少个元素-是不稳定的。
 */
@Test
public void testGreaTestOf() {
    List<Integer> list = Arrays.asList(1, 5, 3, 8, 2);
    List<Integer> listMaxtOfK = Ordering.natural().greatestOf(list, 3);//获取可迭代对象中最大的k个元素。
    log.info("获取最大的k个元素:" + listMaxtOfK.toString());

    List<Integer> listMaxtOfMinik = Ordering.natural().reverse().greatestOf(list, 3);
    // listMaxtOfK.add(1); UnmodifiableCollection 返回的是不可变对象,不可以进行操作
    log.info("获取最大的Minik个元素:" + listMaxtOfMinik.toString());
}

sortedCopy(Iterable) immutableSortedCopy(Iterable)

复制排序后的元素的副本,不过这里不是深复制,需要保证集合元素中的不可变性,返回可变的集合元素和不可变的集合元素

/**
 * 复制一个副本,这里没有进行集合元素的深复制,需要保证集合对象中为不可变对象
 * 这里可以通过sortedCopy,返回一个可变的对象,immutableSortedCopy返回一个不可变的对象
 */
@Test
public void testSortedCopy() {
    List<Integer> list = Arrays.asList(1, 5, 3, 8, 2);
    List<Integer> duplicateList = Ordering.natural().sortedCopy(list);// 返回一个副本
    if (!Objects.equals(list, duplicateList)) {
        log.info("返回的一个副本" + duplicateList.toString());
        duplicateList.add(10);
        log.info("返回的一个可变的副本" + duplicateList.toString());

    }
    List<Integer> duplicateImmutableList = Ordering.natural().immutableSortedCopy(list); // 返回一个不可变的副本
    if (!Objects.equals(list, duplicateImmutableList)) {
        log.info("返回的一个副本" + duplicateImmutableList.toString());
        try {
            duplicateImmutableList.add(10);
        } catch (Exception e) {
            log.info("返回的一个可变的副本不能添加");
        }
    }
}

所有的代码 guava 23.0

OrderExample

package guava.order;

import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * descrption: 排序的简单使用(Ordering是Guava流畅风格比较器Comparator的实现,它可以用来为构建复杂的比较器,以完成集合排序的功能。)
 * authohr: wangji
 * date: 2018-02-07 9:34
 */
@Slf4j
public class OrderExample {

    @Test
    public void testJDKOrder() {
        List<Integer> list = Arrays.asList(1, 5, 3, 8, 2);
        log.info("排序前" + list.toString());
        Collections.sort(list);
        log.info("排序后" + list.toString());
    }

    /**
     * 排序中出现,空指针会异常的!
     */
    @Test(expected = NullPointerException.class)
    public void testJDKOrderIssue() {
        List<Integer> list = Arrays.asList(1, 5, null, 3, 8, 2);
        log.info("排序前" + list.toString());
        Collections.sort(list); // 出现异常...
    }

    /**
     * 将空值放置在最前面的情况
     */
    @Test
    public void testOrderNaturalByNullFirst() {
        List<Integer> list = Arrays.asList(1, 5, null, 3, 8, 2);
        Collections.sort(list, Ordering.natural().nullsFirst());
        log.info("空在最前面-排序后" + list.toString());
    }

    /**
     * 将空值放置在最后面的情况
     */
    @Test
    public void testOrderNaturalByNullLast() {
        List<Integer> list = Arrays.asList(1, 5, null, 3, 8, 2);
        Collections.sort(list, Ordering.natural().nullsLast());
        log.info("空在最后面-排序后" + list.toString());
    }

    /**
     * isOrdered(Iterable)  判断可迭代对象是否已按排序器排序:允许有排序值相等的元素。
     */
    @Test
    public void testOrderNatural() {
        List<Integer> list = Arrays.asList(1, 5, 3, 8, 2);
        Collections.sort(list);
        boolean order = Ordering.natural().isOrdered(list); //是否为按照这样的顺序排好序的!自然的排序
        log.info("排好序的:" + (order == true ? "是的" : "不是"));
    }


    /**
     * reverse()    获取语义相反的排序器
     */
    @Test
    public void testOrderReverse() {
        List<Integer> list = Arrays.asList(1, 5, 3, 8, 2);
        Collections.sort(list, Ordering.natural().reverse());
        log.info("获取最大的元素" + Ordering.natural().max(list).toString());
        log.info("排序后" + list.toString());
    }

    /**
     * 返回元素中的最大的值,同理最小的
     */
    @Test
    public void testMax() {
        List<Integer> list = Arrays.asList(1, 5, 3, 8, 2);
        log.info("获取最大的元素" + Ordering.natural().max(list).toString()); //获取最大的元素8

        log.info("获取最大的元素" + Ordering.natural().reverse().max(list).toString());//获取最大的元素1
    }

    /**
     * 返回一个排序对象中的最大的多少个元素-是不稳定的。
     */
    @Test
    public void testGreaTestOf() {
        List<Integer> list = Arrays.asList(1, 5, 3, 8, 2);
        List<Integer> listMaxtOfK = Ordering.natural().greatestOf(list, 3);//获取可迭代对象中最大的k个元素。
        log.info("获取最大的k个元素:" + listMaxtOfK.toString());

        List<Integer> listMaxtOfMinik = Ordering.natural().reverse().greatestOf(list, 3);
        // listMaxtOfK.add(1); UnmodifiableCollection 返回的是不可变对象,不可以进行操作
        log.info("获取最大的Minik个元素:" + listMaxtOfMinik.toString());
    }

    /**
     * natural():使用Comparable类型的自然顺序, 例如:整数从小到大,字符串是按字典顺序;
     * usingToString() :使用toString()返回的字符串按字典顺序进行排序;
     */
    @Test
    public void testUsingToString() {
        List<Integer> list = Arrays.asList(1, 5, 3, 8, 2);
        Collections.sort(list, Ordering.usingToString());
        log.info("排序后" + list.toString());

        List<String> listString = Lists.newArrayList("wang", "test", "a");
        Collections.sort(listString, Ordering.usingToString());
        log.info("排序后" + listString.toString());
    }

    /**
     * 复制一个副本,这里没有进行集合元素的深复制,需要保证集合对象中为不可变对象
     * 这里可以通过sortedCopy,返回一个可变的对象,immutableSortedCopy返回一个不可变的对象
     */
    @Test
    public void testSortedCopy() {
        List<Integer> list = Arrays.asList(1, 5, 3, 8, 2);
        List<Integer> duplicateList = Ordering.natural().sortedCopy(list);// 返回一个副本
        if (!Objects.equals(list, duplicateList)) {
            log.info("返回的一个副本" + duplicateList.toString());
            duplicateList.add(10);
            log.info("返回的一个可变的副本" + duplicateList.toString());

        }
        List<Integer> duplicateImmutableList = Ordering.natural().immutableSortedCopy(list); // 返回一个不可变的副本
        if (!Objects.equals(list, duplicateImmutableList)) {
            log.info("返回的一个副本" + duplicateImmutableList.toString());
            try {
                duplicateImmutableList.add(10);
            } catch (Exception e) {
                log.info("返回的一个可变的副本不能添加");
            }
        }
    }
}

多字段排序

@Slf4j
public class Worker {
    private Integer workId;
    private String name;

    public Integer getWorkId() {
        return workId;
    }

    public void setWorkId(Integer workId) {
        this.workId = workId;
    }

    public String getName() {
        return name;
    }

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

    public Worker(Integer workId, String name) {
        this.workId = workId;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Worker{" +
                "workId=" + workId +
                ", name='" + name + '\'' +
                '}';
    }
}
package guava.order;

import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Ints;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * descrption: 使用自定义排序规则、多字段排序
 * authohr: wangji
 * date: 2018-02-07 10:21
 */
@Slf4j
public class OrderExample2 {

    public class WorkerIdComparator implements Comparator<Worker> {
        @Override
        public int compare(Worker worker1, Worker worker2) {
            return Ints.compare(worker1.getWorkId(), worker2.getWorkId());
        }
    }

    public class WorkerNameComparator implements Comparator<Worker> {
        @Override
        public int compare(Worker worker1, Worker worker2) {
            return worker1.getName().compareTo(worker2.getName());
        }
    }


    /**
     * http://blog.csdn.net/wenniuwuren/article/details/46361119
     * guava 多参数排序
     * http://ifeve.com/google-guava-ordering/
     * Ordering.from 的使用
     */
    @Test
    public void testFrom() {
        Worker worker = new Worker(1, "wangji");
        Worker worker2 = new Worker(11, "guava");
        Worker worker22 = new Worker(11, "aaa");
        Worker worker3 = new Worker(111, "wangji3");
        List<Worker> workers = Lists.newArrayList(worker, worker2, worker22, worker3);
        Ordering<Worker> orderWorker = Ordering.from(new WorkerIdComparator());
        Collections.sort(workers, orderWorker);
        log.info("单参数:" + workers.toString());

        // compound 相等的情况下,考虑第二个参数进行比较
        Ordering<Worker> orderManyWorker = Ordering.from(new WorkerIdComparator()).compound(new WorkerNameComparator()).reverse();
        Collections.sort(workers, orderManyWorker);
        log.info("多参数:" + workers.toString());

    }
}

 

标签:info,排序,log,Ordering,list,使用,Guava,public
来源: https://www.cnblogs.com/jinloooong/p/13792079.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有