Employee对象:(下面的MySort2有用到这个类)
public class Employee implements Comparable{
private String id; //id号
private String name; //名字
private int age; //年龄
private String department; //部门
static int no =1; //在Employee中自行编号
//构造函数
public Employee(String name, int age, String department) {
this.id = "no."+(no++); //每次给的编号加一
this.name = name;
this.age = age;
this.department = department;
}
//构造函数(如果没有部门号,就设置为“no department”)
public Employee(String name, int age) {
this(name, age, "no department");
}
//hash函数和equals函数
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result
+ ((department == null) ? 0 : department.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (age != other.age)
return false;
if (department == null) {
if (other.department != null)
return false;
} else if (!department.equals(other.department))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
//下面是变量的get、set函数
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
//toString函数
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", age=" + age
+ ", department=" + department + "]";
}
//这里是我们自己写的compareTo(Object o)函数
@Override
public int compareTo(Object o) {
if(o instanceof Employee){
Employee e=(Employee)o;
return this.age-e.age; //直接返回年龄的差,返回大于,等于,小于零。
}
return 0;
}
}
MySort1:
import java.util.HashSet;
import java.util.Iterator;
import java.util.TreeSet;
public class MySort1 {
public static void main(String[] args) {
HashSet set=new HashSet();//该方法:HashSet不能自定义排序,由Employee类中的hashCode()方法的返回值来决定元素的先后顺序。hashCode()方法的返回值是由当前对象本身的数据决定,不能和其他元素进行对比
//TreeSet set=new TreeSet();//该方法:TreeSet能自定义排序,有Employee类中的compareTo()方法的返回值来决定元素的先后顺序。compareTo()方法是由当前对象和参数对象的数据对比结构决定,且对比方式是由我们自己写
//set.add(new String("adcf")); //在这里添加“字符串”元素是可行的,因为Employee类中的compareTo(Object o)方法中可以接收任意类型的参数对象。
set.add(new Employee("Jack", 25));
//set.add(new String("adcf"));在这里添加“字符串”元素是不可行的,因为String类中的compareTo(Object o)方法,不能把原先已经加入集合的Employee对象当作参数传入String类的compareTo(String str)进行比较大小。而如果把该句放在其他add语句之前就可行,因为那样就是把先加入集合的“字符串”作为参数去调用Employee中的compareTo(Object o)方法。
set.add(new Employee("Mike", 26));
set.add(new Employee("Mary", 23));
Iterator it=set.iterator(); //使用迭代器读取数据
//输出
while(it.hasNext()){
System.out.println(it.next());
}
}
}
运行结果:
一、集合排序(方法一)
概念:java.util.Comparator接口适用于一个类有自然顺序的时候。假定对象集合是同一类型,该接口允许把集合排序成自然顺序。该接口中的compare ( T o1, To2)方法: 比较用来排序的两个参数。根据第一个参数小于、等于或大于第二个参数分别返回负、零或正整数。
实现要点:让容器在构造时加入比较器对象。
代码示例:(以TreeMap集合为例,让其中的员工按编号倒序排列。中文排序问题:比较函数对于英文字母与数字等ASCII码中的字符排序都没问题,但中文排序则明显不正确。这主要是Java中使用中文编码GB2312或GBK时,char型转换成int型的过程出现了比较大的偏差。这偏差是由compare方法导致的,因此我们可以自己实现Comparator接口。另外,国际化问题可用Collator类来解决。
java.text.Collator类,提供以与自然语言无关的方式来处理文本、日期、数字和消息的类和接口。)
MySort2:
import java.text.CollationKey;
import java.text.Collator;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class MySort2 {
public static void main(String[] args) {
sort1(); //用自定义比较器(compareTo(Object o))来排序
sort2(); //中文排序
}
//用自定义比较器(compareTo(Object o))来排序
private static void sort1() {
TreeMap map=new TreeMap(new MyCmp());//给TreeMap集合外加一个我们自己写的比较器MyCmp(compareTo(Object o1,Object o2)),由比较器MyCmp(compareTo(Object o1,Object o2))来决定元素的排序方式。
//加元素到map中
map.put("1002", "周军");
map.put("1003", "刘军");
map.put("1012", "王军");
map.put("1001", "李军");
Set entries=map.entrySet();//返回此映射中包含的映射关系的 Set 视图
Iterator it=entries.iterator(); //返回在此 set 中的元素上进行迭代的迭代器
//输出
System.out.println("Sort1测试:-------------------------------");
while(it.hasNext()){ //如果仍有元素可以迭代,则返回 true
Map.Entry en=(Map.Entry)it.next(); //返回迭代的下一个元素
System.out.println(en.getKey()+","+en.getValue());
}
}
private static void sort2() {
TreeMap map=new TreeMap(new MyCmp2());//给TreeMap集合外加一个我们自己写的比较器MyCmp2(compareTo(Object o1,Object o2)),由比较器MyCmp2(compareTo(Object o1,Object o2))来决定元素的排序方式。
//加元素到map中
map.put("周军","1002");
map.put("刘军","1003");
map.put("王军",new Employee("Mike",26));
map.put("李军",new Employee("Rose",23));
Set entries=map.entrySet();//返回此映射中包含的映射关系的 Set 视图
Iterator it=entries.iterator(); //返回在此 set 中的元素上进行迭代的迭代器
//输出
System.out.println("Sort2测试:-------------------------------");
while(it.hasNext()){ //如果仍有元素可以迭代,则返回 true
Map.Entry en=(Map.Entry)it.next(); //返回迭代的下一个元素
System.out.println(en.getKey()+","+en.getValue());
}
}
}
//比较器,(按从小到大的顺序排列)
class MyCmp implements Comparator{
@Override
public int compare(Object o1, Object o2) {
return Integer.parseInt(o1.toString())-Integer.parseInt(o2.toString());
}
}
class MyCmp2 implements Comparator{
Collator c=Collator.getInstance(); //获取当前默认语言环境的 Collator
@Override
public int compare(Object o1, Object o2) {
// 将该 String 转换为一系列可以和其他 CollationKey 按位进行比较的位
CollationKey key1=c.getCollationKey(o1.toString());
CollationKey key2=c.getCollationKey(o2.toString());
return key2.compareTo(key1); //比较此 Key1 与Key2
}
}
结果:
2、Character 按Unicode值的数字大小排序
3、CollationKey 按语言环境敏感的字符串排序
4、Date 按年代排序
5、File 按系统特定的路径名的全限定字符的Unicode值排序
6、ObjectStreamField 按名字中字符的Unicode值排序
7、String 按字符串中字符Unicode值排序
如果一个类不能或不便于实现java.lang.Comparable接口,则可以用实现比较器Comparator接口的方法提供自己的排序行为。同样,如果缺省Comparable行为满足不了工程需要,也可以提供自己的Comparator。
四、编程练习
定义一个类,类里面有一个属性col,类型是集合类型Collection,实现下列方法:可以向col里面添加数据、修改数据、查询数据、删除数据。也就是把这个col当作一个数据存储的容器,对其实现数据的增删改查的方法。
代码实现:
import java.util.ArrayList;
import java.util.Collection;
public class MyCollection {
private Collection col=new ArrayList();
//软件工程,设计方法:自顶而下
//增加
public boolean add(Object obj){
return col.add(obj); //将指定的元素添加到此列表的尾部
}
//删除
public boolean delete(Object obj){
return col.remove(obj); //移除此列表中首次出现的指定元素(如果存在)
}
//修改
public boolean update(Object oldObj,Object newObj){
Object objs[]=col.toArray(); //按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组
col.clear(); //移除此列表中的所有元素
for(int i=0;i<objs.length;i++){
if(objs[i].equals(oldObj)){
objs[i]=newObj; //把需要替换的元素找出来,用newObj替换
}
col.add(objs[i]);
}
return true;
}
//查找
public Collection getAll(){
return col;
}
}