挖掘机技术哪家强

俄罗斯、内蒙古、长白山年货推荐

俄罗斯、内蒙古、长白山年货推荐

 

本人男,85后,山东烟台人,因为工作的原因长期在祖国北部边境地区奔走,骑过蒙古的马,赏过额济纳、阿尔山、满洲里的风景;和老毛子喝过酒,行经额尔古纳河、黑龙江、乌苏里江;去过朝鲜的腹地,体验过各种生活,在日本海里游过泳。边境地区给人一种和内陆完全不一样的感觉,看起来地广人稀有点清冷,但又天高云淡能够让人放飞身心、彻底回归自然。边境地区物产丰盛,加上俄蒙口岸通关往来频繁,个人感觉还是有很多好东西值得推荐给大家,好吃不贵、保证新鲜,主要是年关将至、图个喜庆,重点遴选三个地区的给大家介绍:

一、俄罗斯年货推荐

俄罗斯人对生态环境的保护力度非常之大,龙江地区“三花五罗十八子七十二杂鱼”(都是鱼)非常有名,每到了明水期有几万艘渔船下江捕鱼作业,如果去抚远一定要尝尝全鱼宴,不过这几年宰客太严重,找个小店弄个“江水煮江鱼”就好,好像说偏了……重新来,俄货店这几年在内地开的很多,也去过几家,但是感觉都不大靠谱,还是在边境地区的俄货店更亲民、更可靠,俄罗斯的特产很多,主要有海参、大青虾、啤酒、伏特加、桦树榕、蜂蜜、提拉米苏、巧克力和各种糖果。这方面我们最大的优势是什么,就是保真啊,绝对一手货,俄罗斯拿货。现在这个时代,京东自营全球购都有假货,但是我们绝对给你带来原汁原味俄罗斯货。

(一)俄罗斯海鲜

海鲜这个东西吧,大家都知道,水越冷,肉长的越慢,肉质就越鲜嫩,营养价值就越高。

俄罗斯海参,号称是世界上最好的海参,由于俄罗斯海参崴的海水温度很低,海中的微生物和海藻之类的食物也比较少,生长在这里的海参生长非常缓慢,需要更长的时间才能长成成参,而且体积也要比一般的海参小上很多,正因为如此,俄罗斯海参体内可以积蓄更多的营养,故其营养价值极高,营养价值是国内参的10倍以上。懂行的和喜欢的可以尝试一下。

俄罗斯大青虾,这个虾我在朝鲜的时候吃过,不过是朝鲜人现捞生吃的,剥开壳后通体透明,晶莹剔透,鲜美无比,味道秒杀一切海鲜、秒杀一切日料、秒杀一切人工加工的东西,是我吃过最难忘的东西,让我回味至今,可惜从俄罗斯进过来都是经过冷冻的,不能生吃了,不过做熟了吃也不错,看个人意愿。

俄罗斯大鲍鱼,不知道啥味道,太大了,看着吓人,送礼的可以试试。

俄罗斯野生帝王蟹,生长于俄罗斯勘察加半岛的北太平洋深海300米以下,纯净、零污染的冷水海域,肉质饱满,鲜嫩异常。

(二)俄罗斯酒类

伏特加,大家都很清楚了,俄罗斯人血管里流淌的一半是血液、一半是伏特加,各种品牌,什么沙皇,白鲸,白桦之类。。。懂的自然懂 。人说伏特加就像俄罗斯的特种兵,时刻准备把你一拳放倒,喜欢这口的、爱好伏特加的可以私询。

我本人也好喝点,酒这玩意,最怕喝到假的,对身体伤害超级大。各大网购平台,都有洋酒卖,价格不一,但是真是喝的提心吊胆,自从有个这个途径,我自己喝主要就喝这个了,起码放心不是。

各种啤酒,白兰地等等,俄罗斯的啤酒分号,不同号有不同的酒精度,xo啥的就不一一介绍了,想尝尝的可以买一点。反正还是那句话,保真~。

(三)俄罗斯保健品

桦树茸,重点推荐,糖尿病的克星,还能降血压、降血脂,具体功效,大家百度一下就知道了,总之很强大。特别适合过年的时候送老人、送亲朋,平时自己喝也是很好的,我们单位的大老板天天喝这个,他说效果很好,重点推荐。

各种蜂蜜就不一一说了,蜂巢蜜、黑蜂蜜、各种蜜,俄罗斯的蜂蜜最好的一点就是保真,不像国内蜂蜜加工各种乱七八糟的东西特别多,而且没有欧美系的蜂蜜那么贵,可能因为俄罗斯的蜜蜂足够多……

(四)俄罗斯零食

重点推荐,因为气候严寒,老毛子酷爱烈酒和糖果,各种各种糖琳琅满目,味道都不错,随便尝一个就不会让人失望,简单推荐几个:一是俄罗斯的大头娃娃巧克力,这个不用多说了吧,国宝巧克力,最重要的是便宜……只要十块钱,绝对良心价,这么一块德芙至少得二三十吧,一共有八种口味:推荐牛奶味、原味、巧克力豆味和榛子提子味的,我媳妇特别爱吃,买了无数次。

 

二是俄罗斯的提拉米苏,味道好、味道好、味道好,重要的事情说三遍,礼盒包装也漂亮。

三就是各种糖果了,过年的时候给亲戚朋友和小孩子,就推荐几个有特色的吧。土豆糖,威化,芒果糖,奶罐糖。

还有一种俄罗斯的冰激凌,海象冰激凌,很有名,号称是不怕化的冰激凌,运输过程中如果化了,放到冰箱里冻起来再吃也是一样的,我家冰箱里常年放,因为我媳妇爱吃冰激凌……口味还行,毕竟便宜……

还有俄罗斯的红肠和大列吧,也还可以,但是我不太推荐,红肠主要吃个新鲜,老毛子的口味其实不适合中国人,要吃红肠的话更推荐哈尔滨红肠;大列吧更不用说了,那么大一个,看着都费劲,不过你要是抹点大马哈鱼子酱、夹点蔬菜那另说,喜欢的可以买一点,体积大而不贵……

二、内蒙古年货推荐

一说起内外蒙古,大家的印象可能就是风吹草低、遍地牛羊以及威武雄壮的汉子,的确内蒙古最闻名遐迩的美食就是肉、各种肉,手把肉、烤全羊、焖羊肉,额吉用简单的佐料、并不复杂的烹饪方法,就能完美展现出牛羊肉质地的鲜美、多汁。想象蓝天白云下、绿草清溪间,叫三两好友、全家老少相聚敖包,尽享长生天赐予的人间甄味,确实让人心生向往……闲话少说,推荐年货。

(一)草原羊肉。锡林郭勒、呼伦贝尔是内蒙古羊肉的主要产地,由于水土不同,他们风格迥异又各有千秋,锡林郭勒羊肉个头大、油脂丰富,适合烧烤、做馅料;呼伦贝尔羊肉个头小、水嫩细腻,适合吃火锅;由于不需人工豢养,羊肉没有膻味,口感上佳。现在有一些同志,在内地养羊,等到快到宰杀季的时候把羊都运到内蒙,在草原上放一圈再卖回来,也是没谁了。

(二)牛肉干。成吉思汗的行军粮,正宗的内蒙古牛肉干, 5份鲜牛肉只能制成1份牛肉干,低脂肪、高蛋白,我吃了一次以后顿时感觉以前吃的什么重庆沙嗲牛肉干、五香牛肉干都白吃了,没吃过内蒙古牛肉干的人不足以谈牛肉干,缺点就是有点贵……可以买来送你最心爱的人

(三)马奶酒。是用鲜马奶经过发酵变酸配制而成,一般在3度以下,酒体呈浅金黄色、酸甜适品、醇和清香,具有性温、驱寒、健胃等功效。内地市场上买到的马奶酒很多是奶精、酒精勾兑起来的,没有经过发酵,味道不纯正。

(四)奶茶、奶皮。奶茶是牧民家灶炉上24小时的常客,男主人出行回家,第一时间端上的一定是一碗热腾腾的奶茶。不同于台湾奶茶,蒙古奶茶口味清淡、微咸,茶香和奶香更突出。喝奶茶就要配奶皮,真正的奶皮是把牛奶不断的熬制,一层一层如抽丝剥茧晾干的,我感觉和做奶酪也差不多了,冷却风干后厚度大约在1-2mm,质地饮糯、口口留香,跟奶茶是绝配。

三、长白山年货推荐

辽吉黑边境地区与朝鲜和俄罗斯接壤,边民靠山的吃山、靠水的吃水,吃水的黑龙江居多,吃山的就是长白地区,就是长白山那嘎达,长白山最早被称为不咸山,意思是此山有神在,朝鲜金氏家族极力维护自己的白头山血脉,从此可见长白山的灵秀,长白山美水好,不仅是东北三宝之乡,还是世界三大矿泉水水源地之一,农夫山泉、恒大冰泉、哇哈哈都在这里设厂,大家有机会可以去参观,我最喜欢的农夫山泉系列,有四种动物的,棕熊、马鹿、猞猁取的都是长白山本地的野生动物。废话少说,重点介绍一下长白地区的山珍。

(一)人参

人参是百草之王,我以前对于人参的印象就是电视剧里给皇帝或者大侠吊命用的……现在人参的种植产业已经很成熟,分种类的话有野山参(野外自然生长,几乎绝迹,可遇不可求,朝鲜和老毛子境内还有)、林下参(林下人工播种山参种子,力求生长环境和野山参一致,生长周期可达10-20年,贵)、园参(包山种植,生长周期有3年、6年不等)。野山参和林下参我都吃不起,而且以次充好、以假乱真的太多,我既不是内行,也不需要药用,感觉吃点园参就挺好,一样具有补元治虚、补脉固脱、补脾润肺的功效。

园参根据加工方式不同有红参、白参、干晒参,我就不展开说了,个人推荐干晒参和红参片,干晒参不温不燥比较平和,能够扶正祛邪增强体质,大家买点回去用来煲汤、泡酒、炖鸡都是极好极好的,我做过人参炖海参,吃的那叫一个过瘾;红参温补,长于振奋阳气,有红参片可以泡水喝,我个人血热,觉得会受不了,就没尝试……

(二)灵芝、孢子粉、蛤蟆油

这三个都是好东西,我个人比较推荐孢子粉和蛤蟆油,孢子粉是灵芝发育后期弹射出来的种子,是灵芝的精华所在,具有抑制肿瘤、清理血管、宁心安神、养颜美容的功效,适合送女性、晚上睡眠不好的人以及看望病人。

蛤蟆油,这个名字看起来有点吓人,但蛤蟆油其实是雌性蛤的输卵管,在清代是八珍之首的宫廷贡品,夏天去长白一定要吃一道菜就是炖林蛙,蛤蟆油具有补肾益精、治病后虚弱和体虚衰弱的功效,适合送产后女性以及感觉身体状态不好的男士。

我以前的时候对各种补品是不屑一顾的,那时候吃得好、睡得好、运动多,感觉身上元气满满,等到现在天天加班熬夜,确实感觉身体状态不好,精气神不够了,看到很多人去买一些国外的保健品,各种药丸药片维生素什么的,还有诸如马卡一类的大坑,为什么就不能试试这些经过祖国传统医学和现代医学双重认证的东西呢,诚意推荐大家买一点试试。

(三)山珍

这个就没有什么了,我推荐黑木耳、松子以及山珍礼盒,黑木耳大家都爱吃,好的木耳面大叶薄,手感发轻,背面呈灰色而不是像有的掺假黑木耳,背面有白霜样物质,且比较肥厚。过年了,买点好木耳,炒个鸡蛋或者发一下蘸芥末吃。

松子,关于松子的加工也有很多道道,把两种不同的松子放在一起拌、泡、炒、晒,好中有坏、坏中有好,吃起来发涩有异味,不是正宗的清香味。

礼盒,包装精美,好看好送,也不错,推荐。

本来还应该有一小段介绍朝鲜东西的,但是现在由于制裁,朝鲜什么东西也都过不来了,朝鲜本来也没啥,就是各种海鲜,海参、板蟹、青虾几乎都是自然生长的,绿色纯天然,绝对无污染,味道和口感吃第一口就能感觉出不一样,朝鲜在罗先有一个对外开放的海鲜大市场,里面基本都是中国人在买,现在不知道怎么样了。还有一样好东西,那就是松茸,东北和云南都有松茸,但云南地区更适合松茸生长,出产量大,佳品也就更多,有一次去朝鲜市场里买松茸,才40块钱一斤,如果在国内至少要翻倍了。

最后再做几点特殊声明:第一,这些东西本来只想推荐给我的亲戚朋友,后来朋友说好东西要推广出去,也不想挣多少钱,就是摸索摸索,价格我不敢保证比市场价低,但东西我保证都是真东西。第二,关于货源,俄货是直接俄罗斯的厂家直接送到口岸,内蒙和长白都是和我们单位有长期合作关系,质量绝壁可以保证。第三,要过年了,推荐给大家这些东西就是希望能够在过年团圆的时候给大家带来一些欢乐,再过几天快递就慢了,我也是加班狗一个,也就这十几天时间,大家伙欲购从速,手慢无。

方便纯净的单测-mockito

一、背景

我们在线下通过junit测试的时候,测试后的函数中如果如果有对第三方服务的调用(例如数据库,或者依赖的thrift、pigeon服务),那情况可能会复杂一点,如果第三方服务不稳定(服务没有、数据没有等),那我们的测试用例可能就无法跑通。所以为了能够更方便的只测我们自己的代码逻辑、屏蔽第三方的依赖,我们可以利用mockito来对外部调用进行mock。

二、mockito

1、什么是mockito

Mockito is a mocking framework for Java. Mockito allows convenient creation of substitutes of real objects for testing purposes. Enjoy clean tests with mock objects, improved TDD experience and beautiful mocking API.

2、怎样利用mockito进行单测

maven引用

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>2.8.47</version>
    <scope>test</scope>
</dependency>

 

3、简单示例

import static org.mockito.BDDMockito.when;
import static org.mockito.Mockito.mock;
import static org.testng.Assert.assertEquals;
@Test
public void shouldReturnGivenValueUsingBDDSemantics() {
    //mock
    Flower flowerMock = mock(Flower.class);
    when(flowerMock.getNumberOfLeafs()).thenReturn(TEST_NUMBER_OF_LEAFS);
    //run
    int numberOfLeafs = flowerMock.getNumberOfLeafs();
    //then
    assertEquals(numberOfLeafs, TEST_NUMBER_OF_LEAFS);
}

三、mockito用法

1、mock

写法1:A mockobject = mock(A.class);

写法2:@Mock A mockobject;

mock一个对象,这个mock对象所有行为都会被记录, 默认情况下,所有的函数都有返回值。mock函数默认返回的是null,一个空的集合或者一个被对象类型包装的内置类型,例如0、false对应的对象类型为Integer、Boolean.

2、spy

写法1: A a = spy(A.class);

写法2:@Spy A a;

你可以为真实对象创建一个监控(spy)对象。当你使用这个spy对象时真实的对象也会也调用,除非它的函数被stub了。

3、stub

做测试桩

写法1: when(A.someMethod()).thenReturn(“some result”);

when后面可接 thenReturn thenThrow

写法2:doReturn(“some result”).when(A).someMethod();

doReturn doThrow后接when

注意:测试void函数时需要用写法2

4、verify

验证

//using mock
 mockedList.add("once");
 mockedList.add("twice");
 mockedList.add("twice");
 mockedList.add("three times");
 mockedList.add("three times");
 mockedList.add("three times");
 //following two verifications work exactly the same - times(1) is used by default
 // 下面的两个验证函数效果一样,因为verify默认验证的就是times(1)
 verify(mockedList).add("once");
 verify(mockedList, times(1)).add("once");
 //exact number of invocations verification
 // 验证具体的执行次数
 verify(mockedList, times(2)).add("twice");
 verify(mockedList, times(3)).add("three times");
 //verification using never(). never() is an alias to times(0)
 // 使用never()进行验证,never相当于times(0)
 verify(mockedList, never()).add("never happened");
 //verification using atLeast()/atMost()
 // 使用atLeast()/atMost()
 verify(mockedList, atLeastOnce()).add("three times");
 verify(mockedList, atLeast(2)).add("five times");
 verify(mockedList, atMost(5)).add("three times");

5、参数匹配器(matchers)

6、BDD风格

List<Integer> mockedList = mock(List.class);
//given
given(mockedList.get(0)).willReturn(1);
//when
int result = mockedList.get(0);
//then
Assert.assertEquals(result, 2);

 

四、常用场景示例

5、常用场景示例
@RunWith(MockitoJUnitRunner.class)
public class QixiBookServiceTest {
    //对要测试类的依赖类进行mock
    @Mock
    private QixiBookGateway qixiBookGateway;
    @Mock
    private  MdcGateway mdcGateway;
    @Mock
    DpShopViewGateway dpShopViewGateway;
    //测试类(mock类对象会注入到测试类对象中)
    @InjectMocks
    private QixiBookSerivce qixiBookSerivce;
    @Test
    public void getRoundTest() {
        int cityId = 1;
        int platformId = 20;
        //对依赖类的方法进行mock
        //mock  qixiBookGateway.getQixiBookRound
        when(qixiBookGateway.getQixiBookRound(cityId, platformId)).thenReturn(getDpQixiBookRound());
        //mock  dpShopViewGateway.batchGetShopInfo
        when(dpShopViewGateway.batchGetShopInfo(anyList())).thenReturn(getShopMap());
        //执行测试函数
        QixiBookRoundModel round = qixiBookSerivce.getQixiBookRound(cityId, platformId, nullnull);
        //结果验证
        Assert.assertEquals(round, getResultDpQixiBookRound());
        verify(qixiBookGateway).getQixiBookRound(cityId, platformId);
        verify(dpShopViewGateway).batchGetShopInfo(anyList());
    }
    //...
}

 

 

五、结合idea插件junit generator自动生成测试类

1、安装插件junit generator v2.0

2、配置

OutPut Path: ${SOURCEPATH}/../../test/java/${PACKAGE}/${FILENAME}

修改Junit 4模板

ps:如果有内部类会报错,无法生成测试类

六、mokito + powermock + spock

powermock可以mock static方法

 

参考:

1、官方wikihttps://github.com/mockito/mockito/wiki/FAQ

2、wiki的中文翻译https://github.com/hehonghui/mockito-doc-zh

IntegerCache ByteCache CharacterCache LongCache ShortCache

new Integer(1) 与 Integer.valueOf(1) 的区别

使用 Integer.valueOf(1) 可以使用系统缓存,既减少可能的内存占用,也省去了频繁创建对象的开销。

public static Integer valueOf(int i) {
    assert IntegerCache.high >= 127;
 if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
 return new Integer(i);
}

在[IntegerCache.low, IntegerCache.high] 之前的数字都已被缓存。

private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];
    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            int i = parseInt(integerCacheHighPropValue);
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
        }
        high = h;
        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
    }
    private IntegerCache() {}
}

默认区间是[-128, 127], 通过 VM 参数-XX:AutoBoxCacheMax=<size> 可以配置缓存的最大值.

Short Long Byte Characte也都类似,范围有所不同

区间
设置上限
Integer [-128,127] -XX:AutoBoxCacheMax=<size>
Short [-128,127] 不可设置
Long [-128,127] 不可设置
Byte [-128,127] 不可设置
Character [0,127] 不可设置

Guava Ordering

一、 用途

内存排序

二、 实例化静态方法

排序类 说明
NaturalOrdering 自然序
UsingToStringOrdering 字典序
AllEqualOrdering 全等
ExplicitOrdering 按照有序的列表排序
ArbitraryOrdering 无序
CompoundOrdering 多级排序

1、通过Comparator创建Ordering

通过传入的Comparator方法来比较排序;

源码:

public static <T> Ordering<T> from(Comparator<T> comparator) {
    return (Ordering)(comparator instanceof Ordering?(Ordering)comparator:new ComparatorOrdering(comparator));
}

示例:

Ordering.from(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o1.compareTo(o2);
    }
})

2、自然序:NaturalOrdering

NaturalOrdering会先检查是否为null,是的话就抛异常,然后通过列表元素自己的compareTo方法比较排序;

源码:

//Ordering.java
public static <C extends Comparable> Ordering<C> natural() {
    return NaturalOrdering.INSTANCE;
}
 
//NaturalOrdering.java
final class NaturalOrdering extends Ordering<Comparable> implements Serializable {
    static final NaturalOrdering INSTANCE = new NaturalOrdering();
    private transient Ordering<Comparable> nullsFirst;
    private transient Ordering<Comparable> nullsLast;
    private static final long serialVersionUID = 0L;

    public int compare(Comparable left, Comparable right) {
        Preconditions.checkNotNull(left);
        Preconditions.checkNotNull(right);
        return left.compareTo(right);
    }
	......
}

示例:

List<String> list = Ordering.natural().nullsFirst().sortedCopy(Lists.<String>newArrayList("1", "afc", "aed"));
System.out.println(list);//输出[1, aed, afc]

3、字典序:UsingToStringOrdering

通过元素的toString转为String然后在比较排序

源码:

public int compare(Object left, Object right) {
    return left.toString().compareTo(right.toString());
}

示例:

List<Integer> list = Ordering.usingToString().sortedCopy(Lists.newArrayList(1, 12, 112, 23));
System.out.println(list);
//输出
[1, 112, 12, 23]

4、全相等:AllEqualOrdering

全相等。(稳定排序中)保持原序,可用来把null置后等

源码:

public int compare(@Nullable Object left, @Nullable Object right) {
    return 0;
}

示例:

List<Integer> list = Ordering.allEqual().nullsLast().sortedCopy(Lists.newArrayList(1, 12, null, 112, 23));
System.out.println(list);
//输出
[1, 12, 112, 23, null]

5、无序:ArbitraryOrdering

暂不清楚用途

源码:

static class ArbitraryOrdering extends Ordering<Object> {
    private final AtomicInteger counter = new AtomicInteger(0);
    private final ConcurrentMap<Object, Integer> uids = Platform.tryWeakKeys(new MapMaker()).makeMap();

    ArbitraryOrdering() {
    }

    private Integer getUid(Object obj) {
        Integer uid = (Integer)this.uids.get(obj);
        if(uid == null) {
            uid = Integer.valueOf(this.counter.getAndIncrement());
            Integer alreadySet = (Integer)this.uids.putIfAbsent(obj, uid);
            if(alreadySet != null) {
                uid = alreadySet;
            }
        }

        return uid;
    }

    public int compare(Object left, Object right) {
        if(left == right) {
            return 0;
        } else if(left == null) {
            return -1;
        } else if(right == null) {
            return 1;
        } else {
            int leftCode = this.identityHashCode(left);
            int rightCode = this.identityHashCode(right);
            if(leftCode != rightCode) {
                return leftCode < rightCode?-1:1;
            } else {
                int result = this.getUid(left).compareTo(this.getUid(right));
                if(result == 0) {
                    throw new AssertionError();
                } else {
                    return result;
                }
            }
        }
    }

    public String toString() {
        return "Ordering.arbitrary()";
    }

    int identityHashCode(Object object) {
        return System.identityHashCode(object);
    }
}

6、有序排无序ExplicitOrdering

按照已有的有序的列表,排序无序的列表

源码:

final class ExplicitOrdering<T> extends Ordering<T> implements Serializable {
    final ImmutableMap<T, Integer> rankMap;
    private static final long serialVersionUID = 0L;

    ExplicitOrdering(List<T> valuesInOrder) {
        this(Maps.indexMap(valuesInOrder));
    }

    ExplicitOrdering(ImmutableMap<T, Integer> rankMap) {
        this.rankMap = rankMap;
    }

    public int compare(T left, T right) {
        return this.rank(left) - this.rank(right);
    }

    private int rank(T value) {
        Integer rank = (Integer)this.rankMap.get(value);
        if(rank == null) {
            throw new IncomparableValueException(value);
        } else {
            return rank.intValue();
        }
    }

    public boolean equals(@Nullable Object object) {
        if(object instanceof ExplicitOrdering) {
            ExplicitOrdering that = (ExplicitOrdering)object;
            return this.rankMap.equals(that.rankMap);
        } else {
            return false;
        }
    }

    public int hashCode() {
        return this.rankMap.hashCode();
    }

    public String toString() {
        return "Ordering.explicit(" + this.rankMap.keySet() + ")";
    }
}

示例

//有序的id
List<Integer> orderedList = Arrays.asList(23, 1, 12, 112);
//无序的model
List<Record> nonOrderedList = Lists.newArrayList(new Record(1), new Record(12), new Record(23), new Record(112));
//排序
List<Record> list = Ordering.explicit(orderedList)
        .onResultOf(new Function<Record, Integer>() {
            @Nullable
            @Override
            public Integer apply(@Nullable Record record) {
                return record.getId();
            }
        }).sortedCopy(nonOrderedList);
System.out.println(list);//输出[[id:23], [id:1], [id:12], [id:112]]

7、多级排序CompoundOrdering

循环所有Comparator,如果相等,继续用下一个Comparator,否则直接返回比较结果

源码:

public int compare(T left, T right) {
    int size = this.comparators.size();

    for(int i = 0; i < size; ++i) {
        int result = ((Comparator)this.comparators.get(i)).compare(left, right);
		//不相等就直接返回,不进行后面的比较
        if(result != 0) {
            return result;
        }
    }

    return 0;
}

示例:

Comparator<Record> comparator1 = new Comparator<Record>() {
    @Override
    public int compare(Record o1, Record o2) {
        return o1.getScore().compareTo(o2.getScore());
    }
};
Comparator<Record> comparator2 = new Comparator<Record>() {
    @Override
    public int compare(Record o1, Record o2) {
        return o1.getDistance().compareTo(o2.getDistance());
    }
};
List<Record> nonOrderedList = Lists.newArrayList(new Record(2, 1.0), new Record(2, 100.0), new Record(1, 130.0), new Record(3, 1.0));
List<Record> list = Ordering.compound(Arrays.asList(comparator1, comparator2)).sortedCopy(nonOrderedList);
System.out.println(list);//输出[Record{id=0, score=1, distance=130.0}, Record{id=0, score=2, distance=1.0}, Record{id=0, score=2, distance=100.0}, Record{id=0, score=3, distance=1.0}]

三、链式调用

reverse()  反转
nullsFirst()  null在前
nullsLast()  null在后
onResultOf(Function) Function返回比较的元素类实例
compound(Comparator)
二级排序
lexicographical()  类“字典序”,对于Iterable一位一位比下去,例如array

可以在一个Ordering实例后面挂多个上述方法。

1、reverse()

反转,实际是在比较的时候将参数位置 a,b换为b,a,并不是排序后在反转

源码:

public int compare(T a, T b) {
    return this.forwardOrder.compare(b, a);
}

示例:

List<Integer> nonOrderedList = Arrays.asList(1,4,2,6,9);
List<Integer> list = Ordering.natural().reverse().sortedCopy(nonOrderedList);
System.out.println(list);
//输出
[9, 6, 4, 2, 1]

2、nullsFirst nullsLast

null在前 或 在后

源码:

public int compare(@Nullable T left, @Nullable T right) {
    return left == right?0:(left == null?-1:(right == null?1:this.ordering.compare(left, right)));
}public int compare(@Nullable T left, @Nullable T right) {
 return left == right?0:(left == null?1:(right == null?-1:this.ordering.compare(left, right)));
}

示例:

List<Integer> nonOrderedList = Arrays.asList(1, 4, 2, 6, 9, null);
List<Integer> list = Ordering.natural().nullsFirst().sortedCopy(nonOrderedList);
System.out.println(list);
 
//输出
[null, 1, 2, 4, 6, 9]

3、onResultOf

返回的是ByFunctionOrdering类,比较元素前先应用OnResultOf传入的Function,之后用返回结果再比较

源码:

final Function<F, ? extends T> function;
final Ordering<T> ordering;
private static final long serialVersionUID = 0L;

ByFunctionOrdering(Function<F, ? extends T> function, Ordering<T> ordering) {
    this.function = (Function)Preconditions.checkNotNull(function);
    this.ordering = (Ordering)Preconditions.checkNotNull(ordering);
}
public int compare(F left, F right) {
    return this.ordering.compare(this.function.apply(left), this.function.apply(right));
}

示例:

List<Record> nonOrderedList = Lists.newArrayList(new Record(2, 1.0), new Record(2, 100.0), new Record(1, 130.0), new Record(3, 1.0));
List<Record> list = Ordering.natural().onResultOf(new Function<Record, Integer>() {
    @Nullable
    @Override
    public Integer apply(@Nullable Record record) {
        return record.getScore();
    }
}).sortedCopy(nonOrderedList);
System.out.println(list);
 
//输出
[Record{id=0, score=1, distance=130.0}, Record{id=0, score=2, distance=1.0}, Record{id=0, score=2, distance=100.0}, Record{id=0, score=3, distance=1.0}]

4、compound

该方法返回的就是CompoundOrdering,不过compound()是在其他Odering的基础上再加一个Comparator

源码:

public <U extends T> Ordering<U> compound(Comparator<? super U> secondaryComparator) {
    return new CompoundOrdering(this, (Comparator)Preconditions.checkNotNull(secondaryComparator));
}
 
 
CompoundOrdering(Comparator<? super T> primary, Comparator<? super T> secondary) {
    this.comparators = ImmutableList.of(primary, secondary);
}

CompoundOrdering(Iterable<? extends Comparator<? super T>> comparators) {
    this.comparators = ImmutableList.copyOf(comparators);
}

示例:

List<Record> nonOrderedList = Lists.newArrayList(new Record(2, 200.0), new Record(2, 100.0), new Record(1, 130.0), new Record(2, 1.0));
Comparator<Record> comparator2 = new Comparator<Record>() {
    @Override
    public int compare(Record o1, Record o2) {
        return o1.getDistance().compareTo(o2.getDistance());
    }
};
List<Record> list = Ordering.natural().compound(comparator2).sortedCopy(nonOrderedList);
System.out.println(list);//Record.compareTo只比较了score//输出[Record{id=0, score=1, distance=130.0}, Record{id=0, score=2, distance=1.0}, Record{id=0, score=2, distance=100.0}, Record{id=0, score=2, distance=200.0}]

四、 其他方法

方法 描述
greatestOf(Iterable iterable, int k) 获取可迭代对象中最大的k个元素。堆排序 不稳定排序
leastOf(Iterator iterable, int k) 获取可迭代对象中最小的k个元素。堆排序 不稳定排序
isOrdered(Iterable) 判断可迭代对象是否已按排序器排序:允许有排序值相等的元素。
sortedCopy(Iterable) 判断可迭代对象是否已严格按排序器排序:不允许排序值相等的元素。
min(E, E) 返回两个参数中最小的那个。如果相等,则返回第一个参数。
min(E, E, E, E…) 返回多个参数中最小的那个。如果有超过一个参数都最小,则返回第一个最小的参数。
min(Iterable) 返回迭代器中最小的元素。如果可迭代对象中没有元素,则抛出NoSuchElementException。
max(E, E)

leastOf

流程:

算法:

维持一个2k大小的buffer;每次满了时,清掉较大的一半,剩下k位。

isOrdered isStrictlyOrdered

public boolean isOrdered(Iterable<? extends T> iterable) {
    Iterator it = iterable.iterator();
    Object next;
    if(it.hasNext()) {
        for(Object prev = it.next(); it.hasNext(); prev = next) {
            next = it.next();
            if(this.compare(prev, next) > 0) {
                return false;
            }
        }
    }

    return true;
}

public boolean isStrictlyOrdered(Iterable<? extends T> iterable) {
    Iterator it = iterable.iterator();
    Object next;
    if(it.hasNext()) {
        for(Object prev = it.next(); it.hasNext(); prev = next) {
            next = it.next();
            if(this.compare(prev, next) >= 0) {
                return false;
            }
        }
    }

    return true;
}