自己总结了一下集合对对象的排序问题
最近在学Oracle,时间上还是挺充足的,所以今天复习了一下J2SE的内容。
关于集合Collection接口里的实现类里对对象的排序问题研究了一下,
TreeSet是实现Set这个接口的一个实现类,除了这个接口他还实现了SortedSet这个接口,
它使用红黑树结构来对加入的 对象进行自然排序。看下面这个例子:
import java.util.*;
public class TreeSetDemo {
public static void main(String[] args) {
Set set = new TreeSet();
set.add("justin");
set.add("caterpillar");
set.add("momor");
set.add("justin");
Iterator iterator = set.iterator();
while(iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
}
输出结果会按字典里的顺序进行排序caterpillar justin momor
现在讲我们如果声明一个类,按照类的某个属性进行排序(eg:Student类,age属性进行排序),我总结了 有两种方法可以实现,下面一一介绍:
第一种:由于TreeSet的构造器中有一个public TreeSet(Comparator<? super E> comparator)构造一个新的空 TreeSet,它根据指定比较器进行排序。这样说下去可能会有点模糊,下面举个例子:
TreeSet对对象排序
class Student implements Comparator
{
private int id;
private String name;
private String sex;
private int age;
public Student()
{
}
public Student(int id,String name,String sex,int age)
{
this.id=id;
this.name=name;
this.sex=sex;
this.age=age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compare(Object o1, Object o2) {
return ((Student)o1).getAge()-((Student)o2).getAge();
}
//重写toString方法
public String toString()
{
return "id:"+id+" name:"+name+" age:"+age+" sex"+sex;
}
public static void main(String[] args) {
Student s = new Student();
TreeSet<Student> ts=new TreeSet<Student>(s);
ts.add(new Student(01,"Tom","man",18));
ts.add(new Student(02,"Austin","man",15));
ts.add(new Student(03,"Lily","woman",21));
ts.add(new Student(04,"Emily","man",20));
Iterator it=ts.iterator();
while(it.hasNext())
{
System.out.println(((Student)it.next()));
}
}
}
这 个类实现了Comparator接口,固添加到TreeSet里得对象都会按照我们写的compare()方法去排序。
第二种方法:由于 JDK为集合提供一个Collections类,他就是返回 collection 的静态方法组成,
里面定义了许多方法操作集合类,而且 这些方法都是静态的!我们注意到里面也有我们想要的sort()方法,只不过给定的参数是List接口的实现类,我们应该想到效率高一些的 ArrayList,由于他是不同步的所以要比Vector效率高一些,一样,我们举个例子看看:
class Student implements Comparable
{
private int id;
private String name;
private String sex;
private int age;
public Student(int id,String name,String sex,int age)
{
this.id=id;
this.name=name;
this.sex=sex;
this.age=age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(Object o) {
return ((Student)o).getAge()-this.age;
}
//重写toString方法
public String toString()
{
return "id:"+id+" name:"+name+" age:"+age+" sex"+sex;
}
public static void main(String[] args) {
ArrayList<Student> al=new ArrayList<Student>();
al.add(new Student(01,"Tom","man",18));
al.add(new Student(02,"Austin","man",15));
al.add(new Student(03,"Lily","woman",21));
al.add(new Student(04,"Emily","man",20));
Collections.sort(al);
Iterator it=al.iterator();
while(it.hasNext())
{
System.out.println(((Student)it.next()));
}
}
}
明白了吧?很简单就实现了对象的排序!
集合类应该在J2SE里算是重点,以后项目 中应该经常用到,其实他和数组差不多,只不过数组用来存放相同类型的元素,而集合可以存放不同的数据类型,我们也可以通过泛型规定他的类型,这样操作起来 就不用在转换了!
小弟刚刚学习JAVA,有什么不对的地方望指教!
----------------解决方案--------------------------------------------------------
这种好帖绝对要顶!
----------------解决方案--------------------------------------------------------
谢谢上面的版主,自己在顶下!
----------------解决方案--------------------------------------------------------
以下是引用lampeter123在2010-5-11 08:23:55的发言:
这种好帖绝对要顶!
你以为换个马甲就不认识你了????
----------------解决方案--------------------------------------------------------
也是关于集合框架的 :
对于多个数据的存储和管理,数组和链表结构是较为常见的形式。这两种数据结构能够完成我们需要的诸如增加删除修改选定记录的功能,但是各有各的不足之处。
对于数组来说,由于每个数组的容量都是确定的,每一次通过增加删除操作改变条目数目的时候,都会不可避免的需要重新创建新的数组对象,来容纳新的元素。对于链表结构来说,维护一个较为复杂的实现也并不是没有代价的。
在JAVA语言中,有一种简单的方法来帮助开发人员来维护和管理一组元素,并且提供了常用的各种数据操作的接口,就是集合框架(Collection Framework)。集合框架在JAVA程序中应用非常广泛,是每一个开发人员应该掌握的基本语法。
在面向对象语言中,存在一种对象,它代表了某种对象的集合。在JAVA语言中,我们用一系列的接口及其实现来表示这种集合对象。所有这些集合对象的接口和类,统称为集合框架。集合框架包含的主要接口如下图所示:
大部分的接口继承自Collection接口,而Map是一个不同于Collection的结构。
一般而言,Collection接口及其派生的各种接口和类,对应于广泛的需要频繁增加和删除包含元素的集合,而Map接口则多应用于包含对应关系的集合,比如电话号码簿。
JAVA中泛型的引入,使集合框架的使用更加灵活,也更加安全,但同时也带来了一些容易引起误解的情况,其中最值得引起注意的是泛型修饰的集合的继承关系问题,如下:
import java.util.ArrayList;
import java.util.List;
public class Example_Generics{
public static void main(String args[]){
List<String> list = new ArrayList<String>();
list.add(“hello”);
list.add(“world”);
//试图打印该list
printElements(list);
}
//入口参数为类型object修饰的List
public static void printElements(List<Object> list){
for(Object o : list){
System.out.println(o);
}
}
}
在上面的程序中,我们定义了一个printElements方法,用来遍历打印泛型类型Object修饰的List中的所有元素。在main函数体中,我们定义了一个泛型类型String修饰的List。可是,当我们试图用printElements方法打印String修饰的List时,编译器出乎意料的报告了一个错误:无法将printElements(java.util.List<java.lang.Object>)应用于java.util.List<java.lang.String>。
从表面上看,由于String是Object的子类,于是我们可能想当然的认为String类型修饰的Collection也是Object类型修饰的Collection的子类。如果这一推论成立,那么printElements应该可以打印List<String>。但事实恰恰相反,由于JAVA采用的泛型实现方式,由子类修饰的Collection与由父类修饰的Collection之前并没有继承关系。也就是说List<String>并不是List<Object>的子类。所以在上面的例子中,编译器汇报的错误是入口参数类型不匹配。
那么,如果我们需要定义一个方法,能够接受任意元素类型的List,应该如何来实现呢?在JAVA的泛型中,定义了通配符的概念,来代表任意泛型类型。上例修改如下:
public static void printElements(List<?> list){
for(Object o : list){
System.out.println(o);
}
}
其中,List<?>代表了任意类型元素的List。经此修改,原例程中的编译器错误被修正了,printElements既可以接受List<String>作为参数,也可以接受List<Integer>,以及任意类型修饰的List作为参数。
Map接口:
Map对应的是一种从键key到值value的对应关系的集合。Map中作为key的对象必须满足唯一性的要求,即每个Map对象中不能包含两个形同的key对象,每一个key最多只能应对到一个value对象。
----------------解决方案--------------------------------------------------------
也是关于集合框架的 :
对于多个数据的存储和管理,数组和链表结构是较为常见的形式。这两种数据结构能够完成我们需要的诸如增加删除修改选定记录的功能,但是各有各的不足之处。
对于数组来说,由于每个数组的容量都是确定的,每一次通过增加删除操作改变条目数目的时候,都会不可避免的需要重新创建新的数组对象,来容纳新的元素。对于链表结构来说,维护一个较为复杂的实现也并不是没有代价的。
在JAVA语言中,有一种简单的方法来帮助开发人员来维护和管理一组元素,并且提供了常用的各种数据操作的接口,就是集合框架(Collection Framework)。集合框架在JAVA程序中应用非常广泛,是每一个开发人员应该掌握的基本语法。
在面向对象语言中,存在一种对象,它代表了某种对象的集合。在JAVA语言中,我们用一系列的接口及其实现来表示这种集合对象。所有这些集合对象的接口和类,统称为集合框架。集合框架包含的主要接口如下图所示:
大部分的接口继承自Collection接口,而Map是一个不同于Collection的结构。
一般而言,Collection接口及其派生的各种接口和类,对应于广泛的需要频繁增加和删除包含元素的集合,而Map接口则多应用于包含对应关系的集合,比如电话号码簿。
JAVA中泛型的引入,使集合框架的使用更加灵活,也更加安全,但同时也带来了一些容易引起误解的情况,其中最值得引起注意的是泛型修饰的集合的继承关系问题,如下:
import java.util.ArrayList;
import java.util.List;
public class Example_Generics{
public static void main(String args[]){
List<String> list = new ArrayList<String>();
list.add(“hello”);
list.add(“world”);
//试图打印该list
printElements(list);
}
//入口参数为类型object修饰的List
public static void printElements(List<Object> list){
for(Object o : list){
System.out.println(o);
}
}
}
在上面的程序中,我们定义了一个printElements方法,用来遍历打印泛型类型Object修饰的List中的所有元素。在main函数体中,我们定义了一个泛型类型String修饰的List。可是,当我们试图用printElements方法打印String修饰的List时,编译器出乎意料的报告了一个错误:无法将printElements(java.util.List<java.lang.Object>)应用于java.util.List<java.lang.String>。
从表面上看,由于String是Object的子类,于是我们可能想当然的认为String类型修饰的Collection也是Object类型修饰的Collection的子类。如果这一推论成立,那么printElements应该可以打印List<String>。但事实恰恰相反,由于JAVA采用的泛型实现方式,由子类修饰的Collection与由父类修饰的Collection之前并没有继承关系。也就是说List<String>并不是List<Object>的子类。所以在上面的例子中,编译器汇报的错误是入口参数类型不匹配。
那么,如果我们需要定义一个方法,能够接受任意元素类型的List,应该如何来实现呢?在JAVA的泛型中,定义了通配符的概念,来代表任意泛型类型。上例修改如下:
public static void printElements(List<?> list){
for(Object o : list){
System.out.println(o);
}
}
其中,List<?>代表了任意类型元素的List。经此修改,原例程中的编译器错误被修正了,printElements既可以接受List<String>作为参数,也可以接受List<Integer>,以及任意类型修饰的List作为参数。
Map接口:
Map对应的是一种从键key到值value的对应关系的集合。Map中作为key的对象必须满足唯一性的要求,即每个Map对象中不能包含两个形同的key对象,每一个key最多只能应对到一个value对象。
----------------解决方案--------------------------------------------------------
提示: 作者被禁止或删除 内容自动屏蔽