`
CrystalCoding
  • 浏览: 3020 次
  • 性别: Icon_minigender_1
  • 来自: 西安
最近访客 更多访客>>
社区版块
存档分类
最新评论

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

阅读更多
项目中的一个实际需求,对于数据库中的信息,不同的查询要求以不同的排序方式来展示; 抽象成下面的问题进行解决;

问题描述:
学校的学生信息,包含以下属性: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}
1
0
分享到:
评论
3 楼 CrystalCoding 2013-03-18  
对于这个问题本身而言,数据库排序就已经可以解决问题了;
项目中的需求实现使用了CMDB,也就是在系统安装部署之前,是不知道数据库中会有什么字段的这种场景;
例子只是对于这种场景的一个抽象,可能没表达好~~~
2 楼 tan4836128 2013-03-18  
没看出个所以然啊,楼主想表达什么主题呢?
1 楼 carry_tang1978 2013-03-18  
为什么不在数据库排序,难道楼主把所有数据读到内存排序?

相关推荐

    java策略模式的排序算法例子

    在本示例中,用户界面可能允许选择不同的排序策略,比如通过下拉菜单或按钮来切换。当用户选择一种排序算法时,程序会根据选择创建对应的策略对象,并调用其`sort()`方法对数据进行排序。这种设计使得代码更加灵活,...

    面向对象java排序包

    然后,通过继承这个基类或实现相关的接口,如`Comparator`,可以创建不同的排序策略,如快速排序、归并排序、冒泡排序等。 【继承接口】是Java中实现多态性和扩展功能的关键手段。在这个排序包中,可能定义了一个或...

    java策略模式(排序算法)

    3. **选择排序策略**:选择排序会从未排序的序列中找到最小(或最大)元素,存放到排序序列的起始位置,然后再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。创建一个`...

    Java排序算法包 支持自定义比较条件

    这个"Java排序算法包"提供了对多种排序算法的支持,并且允许用户根据自己的需求自定义比较条件,使得排序功能更加灵活。 1. **排序算法基础**: - 排序是指将一组数据按照特定的顺序进行排列的过程。常见的排序...

    java 策略模式demo

    它可能有一个方法,如sort(),用于执行排序操作,并且可以根据需要动态地切换排序策略。 4. 测试类(StrategyPatternTest):这个测试类会实例化不同的策略对象,并在上下文中使用它们,以验证策略模式的正确性和...

    Java策略模式+案例

    在项目中,环境类`Sorter`会持有`SortingStrategy`的引用,根据用户的选择动态地切换不同的排序策略。 通过这个案例,你可以看到策略模式如何在实际编程中应用,如何创建和使用策略对象,以及如何通过上下文来改变...

    java策略模式示例.zip

    在Java中,策略模式通常涉及到定义一系列算法,并将每一个算法封装起来,使它们可以互相替换,让算法独立于使用它的客户。这个"java策略模式示例.zip"文件显然是为了帮助初学者更好地理解和应用这一模式。 首先,...

    java策略模式源代码

    例如,`SortingStrategy` 接口可能包含 `sort()` 方法,不同的排序策略类将实现这个接口来提供不同的排序算法。 ```java public interface SortingStrategy { void sort(int[] array); } ``` 2. **具体策略类...

    Java 设计模式 策略模式

    在Java中,我们可以定义一个策略接口,比如`SortingStrategy`,它声明了一组方法,如`sort()`,用于执行特定的排序算法。然后,我们创建几个实现这个接口的类,如`BubbleSortStrategy`、`QuickSortStrategy`和`...

    策略模式实现五种排序java代码

    通过使用策略模式,代码更易于维护和扩展,因为每种排序算法都被封装在一个独立的类中,可以单独修改或添加新的排序策略,而不会影响其他代码。此外,这种设计还提供了更好的代码可读性和灵活性,使得系统能够适应...

    java策略模式

    例如,根据用户输入或者配置文件动态选择排序策略。 ```java public class Main { public static void main(String[] args) { int[] array = {5, 3, 8, 1, 9}; // 根据需求选择策略 SortingStrategy strategy...

    java 对象 排序

    当需要对一个类的对象进行排序时,有两种基本策略: 1. **实现Comparable接口**: - 如果一个类的对象需要被排序,那么这个类可以实现`Comparable&lt;T&gt;`接口。`Comparable`接口定义了一个`compareTo()`方法,它比较...

    各种排序算法的策略模式实现

    通过策略模式实现不同排序算法的动态切换,不仅可以显著提高代码的灵活性和可扩展性,还能有效地降低后期维护的成本。本文通过具体的实例演示了如何将策略模式应用于排序算法的实现中,展示了该模式的强大之处。未来...

    Java面向对象思想的排序方法

    在排序问题中,我们可以创建一个`Sortable`接口或抽象类,定义排序的方法,然后让具体的排序算法类实现这个接口或继承这个抽象类。 2. 继承:允许我们创建一个类(子类)继承另一个类(父类),子类可以复用父类的...

    策略模式在实际项目中的应用二

    这些策略可以是排序策略、支付策略、折扣策略等。 导入`build path`下的`lib`目录下的`jar`包,意味着这个项目依赖了一些外部库来支持策略模式的实现。这可能是为了提供额外的数据结构、算法或者特定功能,如日志...

    Java设计模式教程-策略模式Java开发Java经验技

    5. 策略模式在实际问题中的应用示例,如价格计算策略、排序策略等。 6. 策略模式的优点和适用场景,以及可能存在的缺点和注意事项。 文件名"赚钱项目"可能与实际的项目案例有关,资料中可能包含如何运用策略模式...

    Java几种常见的排序算法(经典收藏)

    根据给定的文件信息,我们可以深入探讨几种在Java中实现的经典排序算法,这些算法是数据结构与算法领域的...理解和掌握这些排序算法不仅有助于提高编程能力,还能在实际项目中根据具体需求灵活选择最合适的排序策略。

    策略模式 java 实现冒泡、快排、归并三种算法

    用户可以在运行时选择合适的排序策略,同时,代码还支持从文件中读取待排序的数据,提供了良好的可扩展性和实用性。这个项目不仅展示了策略模式的运用,也涵盖了基础的排序算法和文件读取操作,是学习和实践面向对象...

    【设计模式】策略模式Demo(java代码)

    这种灵活性使得策略模式在处理需要多种算法或行为的场景中非常有用,比如游戏中的角色行为、数据排序等。 通过分析这个Demo,我们可以深入理解设计模式如何提高代码的可扩展性和可维护性,以及如何在实际项目中应用...

    Java集合排序及java集合类详解

    Java集合框架是Java编程语言中的一个核心组成部分,它为存储、管理和操作对象提供了一种高效且灵活的方式。本文将深入探讨Java集合框架...在实际开发中,根据需求选择合适的容器类型和排序策略,能够显著提升程序性能。

Global site tag (gtag.js) - Google Analytics