码迷,mamicode.com
首页 > 其他好文 > 详细

面向对象,集合篇(2)

时间:2015-08-14 22:49:34      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:面向对象   集合排序   

一、集合排序(方法一)
       概念: java.lang.Comparable接口适用于一个类有自然顺序的时候。假定对象集合是同一类型,该接口允许把集合排序成自然顺序。该接口中的int compareTo( T obj )方法: 比较当前实例对象与对象obj,如果位于对象obj之前,返回负值;如果两个对象在排序中位置相同,则返回0;如果位于对象obj后面,则返回正值。
       实现要点:让被放置到容器的对象类实现Comparable接口。由其中所实现的方法compareTo( )决定对象之间的排列顺序。
       注意: TreeSet和TreeMap都是有排序功能的集合,而HashSet是没有排序功能的集合。
       代码示例:(以TreeSet集合为例,让集合中的String对象与Employee对象按指定规则进行排序。)

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
	}
}

结果:

技术分享

三、综述
     在JDK1.2中,有14个类实现了Comparable接口,这些类中指定的自然排序如下:
          1、BigDecimal,BigInteger,Byte,Double,Float,Integer,Long,Short按数字大小排序
          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;
	}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

面向对象,集合篇(2)

标签:面向对象   集合排序   

原文地址:http://blog.csdn.net/xionghui2013/article/details/47667507

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!