面向对象,集合篇(2)

一、集合排序(方法一)

概念: 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;
	}
}

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

时间: 2024-10-05 23:11:04

面向对象,集合篇(2)的相关文章

面向对象 集合篇

集合概念: 集合本质上是一个动态数组 2.命令引用:using system.collections 2.1 Arratlist 属性(count) 数量 .属性2(capactity) 有几个位子 //集合里包括属性和方法2.2 arratlist list =new arraylist(); list.add(欲添加的值) object 类型的 为什么这里可以使object 类型的? 是因为object 是所有类型的父类,父类引用指向子类对象 所有类型都可以放在集合中去. 2.3 集合与数组

面向对象集合篇

1.动态数组ArrayList 2.List<T> 3.字典 Dictionary <string,Dog> dic = new Dictionary<string,Dog> (); 4.栈操作出栈pop 入栈push 获取栈顶元素peek 5.队列是两段开头的羽毛球筒子 6.Dequeue出队,Enqueue入队. 原文地址:https://www.cnblogs.com/xiaomao21/p/8330779.html

黑马程序员——集合篇

------- android培训.java培训.期待与您交流! ---------- 1.集合类 为什么出现集合类? 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一 种方式. 数组和集合类同是容器,有何不同? 数组虽然也可以存储对象,但长度是固定的:集合长度是可变的.数组中可以存储基本数据类型,集合只能存储对象. 集合类的特点 集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象. 2.集合框架的构成及分类 3.

【JAVA秒会技术之秒杀面试官】秒杀Java面试官——集合篇(一)

[JAVA秒会技术之秒杀面试官]秒杀Java面试官--集合篇(一) [JAVA秒会技术之秒杀面试官]JavaEE常见面试题(三) http://blog.csdn.net/qq296398300/article/category/6876287

backbonejs中的集合篇(一)

一:集合概念 集合是多个模型,如果把模型model理解为表结构中的行,那么集合collection就是一张表,由多个行组成.我们经常需要用集合来组织和管理多个模型. 二:创建集合 1:扩展Backbone.Collection对象,指定为哪个模型创建集合,传参数model. var _collection = Backbone.Collection.extend({ model: _model }); 2:创建集合实例,传模型数组参数来初始化; 现假定_model的dafault属性为(name

部署SCCM 2012R2之七:安装客户端代理&创建集合篇

由于前段时间公司事情较多,博客也好久未更新,今天就按照之前所讲的内容继续前进,在微软的产品中许多客户端都需要代理的支持,才能完成某些工作任务,如SCVMM.SCCM.SCOM都是如此,在SCCM中不管是软件分发.软件资产.硬件资产,远程控制等都需要安装SCCM的代理. 而创建集合主要是便于管理员根据某些集合而做相应的策略部署,集合主要有用户集合和设备集合.在用户集合中可以创建以OU(如IT.Sales.HR)等为单位的集合,也可以创建以区域(如上海.北京.广州)等为单位的集合,设备集合可以创建不

面向对象(高级篇之抽象类与接口的应用)

抽象类的实际应用-----模板设计 接口的实际应用--------制定标准 设计模式-------工厂设计 程序在接口和子类之间加入了一个过渡端,通过此过渡端取得接口的实例化对象. 设计模式-------代理设计 所谓的代理设计就是指由一个代理主题来操作真实主题,真实主题执行具体的业务操作,而代理主题负责其他相关业务的处理. 相当于我玩一个游戏需要登录游戏,在这个登录的时候可以设计两个类,一个是登录,另一个是检验你的用户名与密码,而登录是附着在检验类上的. 设计模式-------适配器设计 对于

JUC源码分析-集合篇(三)ConcurrentLinkedQueue

JUC源码分析-集合篇(三)ConcurrentLinkedQueue 在并发编程中,有时候需要使用线程安全的队列.如果要实现一个线程安全的队列有两种方式:一种是使用阻塞算法,另一种是使用非阻塞算法.使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入队和出队用不同的锁)等方式来实现.非阻塞的实现方 式则可以使用循环 CAS 的方式来实现.本节让我们一起来研究一下 Doug Lea 是如何使用非阻塞的方式来实现线程安全队列 ConcurrentLinkedQueue 的,相信从大师

JUC源码分析-集合篇(五)BlockingQueue 阻塞式队列实现原理

JUC源码分析-集合篇(五)BlockingQueue 阻塞式队列实现原理 以 LinkedBlockingQueue 分析 BlockingQueue 阻塞式队列的实现原理. 1. 数据结构 LinkedBlockingQueue 和 ConcurrentLinkedQueue 一样都是由 head 节点和 last 节点组成,每个节点(Node)由节点元素(item)和指向下一个节点(next)的引用组成,节点与节点之间就是通过这个 next 关联起来,从而组成一张链表结构的队列.默认情况下

JUC源码分析-集合篇(七)PriorityBlockingQueue

JUC源码分析-集合篇(七)PriorityBlockingQueue PriorityBlockingQueue 是带优先级的无界阻塞队列,每次出队都返回优先级最高的元素,是二叉树最小堆的实现. PriorityBlockingQueue 数据结构和 PriorityQueue 一致,而线程安全性使用的是 ReentrantLock. 1. 基本属性 // 最大可分配队列容量 Integer.MAX_VALUE - 8,减 8 是因为有的 VM 实现在数组头有些内容 private stati