当前位置:首页 > 开发 > 编程语言 > Java > 正文

Java排序(灵活定义排序策略)

发表于: 2013-03-17   作者:CrystalCoding   来源:转载   浏览次数:
摘要: 项目中的一个实际需求,对于数据库中的信息,不同的查询要求以不同的排序方式来展示; 抽象成下面的问题进行解决; 问题描述: 学校的学生信息,包含以下属性:ID、姓名、所在城市、成绩; 所有学校的学生信息统一存放,但不同学校查询信息时要求按照不同的排序策略显示,如何编写统一的排序方法满足这种需求; 学生信息如下所示(简单起见,保存在一个properties文件中): 记录=ID,姓名
项目中的一个实际需求,对于数据库中的信息,不同的查询要求以不同的排序方式来展示; 抽象成下面的问题进行解决;

问题描述:
学校的学生信息,包含以下属性:ID、姓名、所在城市、成绩;
所有学校的学生信息统一存放,但不同学校查询信息时要求按照不同的排序策略显示,如何编写统一的排序方法满足这种需求;
学生信息如下所示(简单起见,保存在一个properties文件中):
记录=ID,姓名,所在城市,成绩
stu01=001,zhangsan,xian,90
stu02=002,zhangsan,nanjing,85
stu03=002,zhangsan,beijing,90
stu04=002,lisi,shanghai,90
stu05=003,wangwu,guangdong,95
stu06=004,qianqi,xinjiang,60

问题解决:
将问题分解为下面散步来循序渐进的解决;

1.学生具有ID、姓名两个属性,要求先按照ID排序,ID相同的按照姓名排序;
这是一个比较典型的java排序问题,首先创建一个CommonStudent的Bean类;
实现比较算法如下:
/**
 * 普通学生的比较类
 * 先根据id排序,后根据name排序
 */
import java.util.Comparator;

import com.crystalcoding.beans.CommonStudent;

@SuppressWarnings("rawtypes")
public class CommonComp implements Comparator
{
    public int compare(Object obj0, Object obj1)
    {
        CommonStudent s0 = (CommonStudent) obj0;
        CommonStudent s1 = (CommonStudent) obj1;
        //先比较ID的大小
        int compId = s0.getId().compareTo(s1.getId());
        //三段式返回
        return 0 != compId ? compId : s0.getName().compareTo(s1.getName());
    }
}

排序结果如下:
No.0: id = 001 name = zhangsan
No.1: id = 002 name = lisi
No.2: id = 002 name = zhangsan
No.3: id = 002 name = zhangsan
No.4: id = 003 name = wangwu
No.5: id = 004 name = qianqi
需要注意的是:如果ID是String类型的话,那么是按字典顺序排列的,即:8>15

2.扩展:学生的信息不限定,即:可能有所在城市的信息,也可能没有,甚至可能有联系方式等属性;
这里有一个小把戏来解决,在学生的Bean类中,添加一个HashMap用于保存学生的所有信息(这里不展示get、set以及toString方法):
//信息丰富的学生类
public class EnrichStudent
{
    private String id;

    private String name;

    private HashMap<String, String> attributes;
}

仍旧使用问题1当中的Compare方法即可实现;

3.扩展:不同的学校期望以不同的方式来排序;
需要在实现的比较类中添加一个属性来保存比较的属性:
package com.crystalcoding.sort.test;

import java.util.Comparator;
import java.util.List;

import com.crystalcoding.beans.EnrichStudent;

@SuppressWarnings("rawtypes")
public class ComplicateComp implements Comparator
{
    //用于保存比较的属性列表
    private List<String> keys;
    
    //比较类的构造函数
    public ComplicateComp(List<String> keys)
    {
        this.keys = keys;
    }
    
    public int compare(Object obj0, Object obj1)
    {
        EnrichStudent s0 = (EnrichStudent) obj0;
        EnrichStudent s1 = (EnrichStudent) obj1;
        //属性列表遍历
        for (int i = 0; i < keys.size(); i++)
        {
            String key = keys.get(i);
            String value0 = s0.getAttributes().get(key);
            String value1 = s1.getAttributes().get(key);
            int compResult = value0.compareTo(value1);
            if (0 != compResult)
            {
                return compResult;
            }
            else
            {
                if (i == keys.size() - 1)
                {
                    return 0;
                }
            }
        }
        return 0;
    }
}

该比较类调用如下所示(更加通俗的排序):
    public static void main(String[] args) throws IOException
    {
        //普通情况的排序
        List<CommonStudent> commonList = initCommonList();
        Collections.sort(commonList, new CommonComp());
        print(commonList);
        
        //信息丰富的学生排序
        List<EnrichStudent> enrichList = initComplicateList();
        Collections.sort(enrichList, new EnrichComp());
        print(enrichList);
        
        //更加通俗的排序
        List<EnrichStudent> complicateList = initComplicateList();
        List<String> keys = new ArrayList<String>();
        keys.add("id");
        keys.add("name");
        keys.add("count");
        Collections.sort(complicateList, new ComplicateComp(keys));
        print(complicateList);
    }

展示了其中的一种排序策略:按照ID、姓名、成绩排序,结果如下:
No.0: id = 001 name = zhangsan attributes = {id=001, count=90, address=xian, name=zhangsan}
No.1: id = 002 name = lisi attributes = {id=002, count=90, address=shanghai, name=lisi}
No.2: id = 002 name = zhangsan attributes = {id=002, count=85, address=nanjing, name=zhangsan}
No.3: id = 002 name = zhangsan attributes = {id=002, count=90, address=beijing, name=zhangsan}
No.4: id = 003 name = wangwu attributes = {id=003, count=95, address=guangdong, name=wangwu}
No.5: id = 004 name = qianqi attributes = {id=004, count=60, address=xinjiang, name=qianqi}

Java排序(灵活定义排序策略)

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
[关键字]:java,design pattern,设计模式,《Java与模式》学习,Strategy Pattern,策略模式 [环境]:Sta
[关键字]:java,design pattern,设计模式,《Java与模式》学习,Strategy Pattern,策略模式 [环境]:Sta
[关键字]:java,design pattern,设计模式,《Java与模式》学习,Strategy Pattern,策略模式 [环境]:Sta
给出10个数,使用某种排序方法,按照从小到大的顺序输出个个数。 根据要求,首先得给出这10个数,这
先推荐一篇关于排序算法的文章:http://www.cppblog.com/guogangj/archive/2009/11/13/100876.html
谷歌和百度这类全网搜索引擎的排序策略非常明显; 很多平台网站会开发自己的搜素,如果要排序维度越
冒泡排序 冒泡排序比较好理解,但是效率比较低, 冒泡排序的基本思想是:每一次将最具有特征的一个数
1991年计算机先驱奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德(RobertW.Floyd)和威廉姆斯
9 排序
直接插入排序 排序过程 整个排序过程为n-1趟插入,即先将序列中第1个记录看成是一个有序子序列,然
10 排序
void Insert_Sort(RecType R[],int n) { int i,j; for(i=2;i<=n; i++) //表示待插入元素的下标 {
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号