常用类之比较器
1 出现的背景
在java中涉及到数组,对象的排序问题
java中的对象,正常情况下,只能进行比较:==或者!=,不能使用>或者<,但是在实际的开发场景中,我们需要对多个对象进行排序,言外之意,就需要比较对象的大小,以什么来衡量对象的大小,如何实现?
2 实现对象排序的方式
- 自然排序:java.lang.Comparable
- 定制排序:java.util.Comparator
3 使用
3.1 Comparable:自然排序
String,包装类等实现了Comparable接口,重写compareTo()方法,给出了比较两个对象的大小的方式。
重写compareTo(obj)的规则:
-
如果当前对象this大于形参对象obj,则返回正整数。
-
如果当前对象this小于形参对象obj,则返回负整数。
-
如果当前对象this等于形参对现象obj,则返回0。
对于自定义类进行排序,自定义类需要实现Comparable接口,若不实现Comparable接口,会报异常:java.lang.ClassCastException: com.atguigu.comparejava.Goods cannot be cast to java.lang.Comparable
需求:实现自定义类的排序
1)自定义类实现Comparable接口,重写toString方法
class Goods implements Comparable { private String name; private double price;
<span class="token keyword">public</span> <span class="token function">Goods</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token function">Goods</span><span class="token punctuation">(</span>String name<span class="token punctuation">,</span> <span class="token keyword">double</span> price<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>price <span class="token operator">=</span> price<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> String <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setName</span><span class="token punctuation">(</span>String name<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">double</span> <span class="token function">getPrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> price<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setPrice</span><span class="token punctuation">(</span><span class="token keyword">double</span> price<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">this</span><span class="token punctuation">.</span>price <span class="token operator">=</span> price<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * 指明该类比较大小的方式:先按照价格从低到高,然后按照产品名称从低到高。 * * @param o:待比较的对象 * @return :结果。正数说明this大,负数说明obj大,o则相等 */</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">compareTo</span><span class="token punctuation">(</span>Object o<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">if</span> <span class="token punctuation">(</span>o <span class="token keyword">instanceof</span> <span class="token class-name">Goods</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> Goods goods <span class="token operator">=</span> <span class="token punctuation">(</span>Goods<span class="token punctuation">)</span> o<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>price <span class="token operator">></span> goods<span class="token punctuation">.</span>price<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>price <span class="token operator"><</span> goods<span class="token punctuation">.</span>price<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{<!-- --></span> <span class="token comment">//return 0;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">.</span><span class="token function">compareTo</span><span class="token punctuation">(</span>goods<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">RuntimeException</span><span class="token punctuation">(</span><span class="token string">"你输入的商品类型不对!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> String <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token string">"Goods{"</span> <span class="token operator">+</span> <span class="token string">"name='"</span> <span class="token operator">+</span> name <span class="token operator">+</span> <span class="token string">'\''</span> <span class="token operator">+</span> <span class="token string">", price="</span> <span class="token operator">+</span> price <span class="token operator">+</span> <span class="token string">'}'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
2)代码测试:
@Test
public void testCompareGoods() {
Goods[] goods = new Goods[4];
goods[0] = new Goods("lenovo", 34);
goods[1] = new Goods("xiaomi", 50);
goods[2] = new Goods("dell", 50);
goods[3] = new Goods("huawei", 50);
Arrays.sort(goods);
System.out.println(Arrays.toString(goods));
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
3.2 Comparator接口的使用:定制排序
1)排序:当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用Comparator的对象来排序。
2)实现compare(Object o1,Object o2)方法,比较o1,o2的大小:
- 如果返回值是正数则o1>o2;
- 负数则o1<o2;
- 0则相等。
简单使用
/** *按照名字升序排列,如果名字相同,按照价格降序进行排列 */ @Test public void testCompareGoods02() { Goods[] goods = new Goods[5]; goods[0] = new Goods("lenovo", 34); goods[1] = new Goods("xiaomi", 50); goods[2] = new Goods("dell", 50); goods[3] = new Goods("huawei", 50); goods[3] = new Goods("huawei", 70);
<span class="token comment">//产品名称从低到高,价格从高到低</span> Arrays<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span>goods<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Comparator</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">compare</span><span class="token punctuation">(</span>Object o1<span class="token punctuation">,</span> Object o2<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">if</span> <span class="token punctuation">(</span>o1 <span class="token keyword">instanceof</span> <span class="token class-name">Goods</span> <span class="token operator">&&</span> o2 <span class="token keyword">instanceof</span> <span class="token class-name">Goods</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> Goods g1 <span class="token operator">=</span> <span class="token punctuation">(</span>Goods<span class="token punctuation">)</span> o1<span class="token punctuation">;</span> Goods g2 <span class="token operator">=</span> <span class="token punctuation">(</span>Goods<span class="token punctuation">)</span> o2<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>g1<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span>g2<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token operator">-</span>Double<span class="token punctuation">.</span><span class="token function">compare</span><span class="token punctuation">(</span>g1<span class="token punctuation">.</span><span class="token function">getPrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> g2<span class="token punctuation">.</span><span class="token function">getPrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> g1<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">compareTo</span><span class="token punctuation">(</span>g2<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>Arrays<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span>goods<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31