• 按对象某属性排序的几种方法


    按对象某属性排序的几种方法:

    第一种,可以实现边添加边排序,需要用到TreeSet

    第二种,用数组存放对象们,但是不需单独取出某属性排列好再重存,而是在原数组上用比较器重新排一次序。需要用到Arrays.sort(arr,comparator)

    第三种,用集合类中的list的子类存放对象们,然后排序。需要用到Collections.sort(list,comparator)

    一、TreeSet

    创建:

    序号构造函数的说明
    1 TreeSet ()

    此构造函数构造空树集,将在根据其元素的自然顺序按升序排序。

    2 TreeSet (集合 c)

    此构造函数生成树的集合,它包含的元素的集合 c。

    3 TreeSet (比较器 comp)

    此构造函数构造一个空树集,将根据给定的比较器进行排序。

       

    增:

    boolean add(E e)
    将指定的元素添加到这套,如果它已不存在。
    boolean addAll(Collection<? extends E> c)
    在加入这一组指定的集合中添加的所有元素。

     删:

    boolean remove(Object o)
    从这一组中移除指定的元素,如果它存在。
    void clear()
    从这一组中移除所有元素。

    查:

    Comparator<? super E> comparator()
    返回用于排序在这集,或元素,如果这套使用自然排序其元素的比较。
    boolean contains(Object o)
    如果此集合包含指定的元素,则返回true 。
       
    boolean isEmpty()
    如果此集不包含任何元素,则返回true 。
    Iterator<E> iterator()
    返回迭代器中这套以升序排序的元素。
       
       
    int size()
    在这套 (其基数) 中返回的元素的数目。
       

    遍历:通过迭代器遍历。

    Iterator it=treeset.iterator();
    while(it.hasNext()){
      //操作当前结点。
    }

    代码实现:

     TreeSet是一个有序集合,TreeSet中的元素将按照升序排列。

     TreeSet存储对象的时候, 可以排序, 其中Integer有默认排序方法, String有默认排序方法,,而自定义的类对象存储的时候则没有顺序,需要自定义排序算法。

    如果想把自定义类的对象存入TreeSet进行排序,或者对int,String对象想定义自己的排序方法,有以下两种方法:

            排序的第一种方式:

               让元素自身具备比较性。让元素实现Comparable接口,覆盖compareTo方法,在方法内定义比较算法, 根据大小关系, 返回正数负数或零。在使用TreeSet存储对象的时候, add()方法内部就会自动调用compareTo()方法进行比较, 根据比较结果使用二叉树形式进行存储。
           排序的第二种方式:

           自定义比较器。 定义一个类实现Comparator接口,覆盖compare方法。将该Comparator接口子类对象传递给TreeSet集合构造函数。

    第一种:类定义时实现Comparable接口,定义自身的比较算法。

    此处以Person类为例,把人名和年龄作为对象属性,存放进treeset中,按照年龄的升/降序保存。

    此处以Person类为例,把人名和年龄作为对象属性,存放进treeset中,按照年龄的升/降序保存。

     1 public class TreeSetTest {
     2 
     3 public static void main(String[] args) {
     4 TreeSet people=new TreeSet();
     5 people.add(new Person("小明", 20));
     6 people.add(new Person("小张", 30));
     7 people.add(new Person("小刘", 18));
     8 people.add(new Person("小林", 17));
     9 people.add(new Person("小刘", 35));
    10 
    11 Iterator it=people.iterator();
    12 while(it.hasNext()){
    13   System.out.println(it.next());
    14   }
    15 }
    16 
    17 }
    18 class Person implements Comparable{  //定义类时,实现比较接口
    19 
    20 String name;
    21 int age;
    22 
    23 public Person() {
    24 }
    25 
    26 public Person(String name, int age) {
    27 this.name = name;
    28 this.age = age;
    29 }
    30 
    31 public String toString(){
    32 return "姓名:"+name+",年龄:"+age;
    33 }
    34 /*
    35 compareTo(Object o):参数是从根节点开始依次传进来的结点,直到确定合适的位置用来安插新节点。
    36 方法返回三个值,分别对应三种动作:返回1,则继续递进,把新结点与下一层的结点进行比较;
    37 返回0,则该属性值不足以决定两结点位置区别,再定义其他属性的比较算法来进一步比较两对象;
    38 返回-1,则新结点优先级大于当前层,往上一层比较;
    39 */
    40 public int compareTo(Object o) {
    41 Person curr=(Person) o;
    42 //int result = this.age<curr.age?1:(this.age==curr.age?0:-1);//降序排列:新插入结点与当前比较层结点的属性比较,小则返回1,继续往下一层比较
    43 int result = this.age>curr.age?1:(this.age==curr.age?0:-1);//升序排列:新插入结点与当前比较层结点的属性比较,大则返回1,继续往下一层比较
    44 if(result==0){
    45 result=this.name.compareTo(curr.name);//age相同时,则以姓名的字母序来排列。前面说过,int、string类型是有默认排列算法的,所以此处直接用 
    46 }
    47 return result;
    48 } 
    49 }
    View Code

    第二种:定义Comparator接口的实现类(比较器),在类中定义对象的比较算法。在创建Treeset时把比较器对象传进去。

     1 public class TreeSetTest {
     2 
     3 /**
     4 * @param args the command line arguments
     5 */
     6 public static void main(String[] args) {
     7 TreeSet people=new TreeSet(new MyComparator());//把比较器对象作为TreeSet的构造函数参数
     8 people.add(new Person("小明", 20));
     9 people.add(new Person("小张", 30));
    10 people.add(new Person("小刘", 18));
    11 people.add(new Person("小林", 17));
    12 people.add(new Person("小刘", 35));
    13 
    14 Iterator it=people.iterator();//用迭代器遍历treeset
    15 while(it.hasNext()){
    16 System.out.println(it.next());
    17 }
    18 }
    19 
    20 }
    21 class Person {
    22 
    23 String name;
    24 int age;
    25 
    26 public Person() {
    27 }
    28 
    29 public Person(String name, int age) {
    30 this.name = name;
    31 this.age = age;
    32 }
    33 
    34 public String toString(){
    35 return "姓名:"+name+",年龄:"+age;
    36 }
    37 
    38 }
    39 class MyComparator implements Comparator{//实现Comparator接口,自定义比较器,实现compare方法定义比较算法
    40 
    41 /*
    42 compare(o1,o2):参数o1是待插入的结点,o2是从树根节点逐层遍历下来的结点,用于当前比较。
    43 方法返回三个值,分别对应三种动作:返回1,则继续递进,把新结点与下一层的结点进行比较;
    44 返回0,则该属性值不足以决定两结点位置区别,再定义其他属性的比较算法来进一步比较两对象;
    45 返回-1,则新结点优先级大于当前层,往上一层比较;
    46 
    47 */
    48 public int compare(Object o1, Object o2) {
    49 Person p1=(Person)o1;
    50 Person p2=(Person)o2;
    51 
    52 int result=p1.age<p2.age?1:(p1.age==p2.age?0:-1);//降序排列
    53 //int result=p1.age<p2.age?1:(p1.age==p2.age?0:-1);//升序排列
    54 
    55 if(result==0){
    56 result=p1.name.compareTo(p2.name);
    57 }
    58 return result;
    59 }
    60 
    61 }
    View Code

    二、用数组存放对象,用比较器改变sort()排序方法

      数组本身有默认的排序方法,针对int、string等基本类型有默认的sort()方法。而针对类对象的排序,可以给sort()方法传进一个比较器对象,赋予其排序的算法。

     1 public class ArraysTest {
     2 
     3 public static void main(String[] args) {
     4 
     5 Person[] people=new Person[5];
     6 people[0]=(new Person("小明", 20));
     7 people[1]=(new Person("小张", 30));
     8 people[2]=(new Person("小刘", 18));
     9 people[3]=(new Person("小林", 17));
    10 people[4]=(new Person("小刘", 35));
    11 
    12 Arrays.sort(people,new MyCompare());//传进来一个比较器对象,使数组按比较器定义的规则来排序
    13 for(Person i:people){
    14 System.out.println(i);
    15 }
    16 
    17 }
    18 
    19 }
    20 class Person {
    21 
    22  
    23 
    24 String name;
    25 int age;
    26 
    27  
    28 
    29 public Person() {
    30 }
    31 
    32  
    33 
    34 public Person(String name, int age) {
    35 this.name = name;
    36 this.age = age;
    37 }
    38 
    39 public String toString(){
    40 return "姓名:"+name+",年龄:"+age;
    41 }
    42 
    43 }
    44 
    45  
    46 
    47 class MyCompare implements Comparator<Person>{//定义比较器
    48 
    49  
    50 
    51 /*
    52 
    53 重写比较方法compare(o1,o2):
    54 
    55 方法传进来两个对象,用两个对象的某属性进行对比,返回一个int。
    56 
    57 int>0,则o1排在o2后面;
    58 
    59 int<0,则o1排在o2前面;
    60 
    61 int=0,则维持原相对位置,即原来存放时o1、o2的前后地址顺序。
    62 
    63 */
    64 public int compare(Person o1, Person o2) {
    65 int result;
    66 if(o1.age>o2.age){
    67 result=1;
    68 }
    69 else if(o1.age<o2.age){
    70 result=-1;
    71 }
    72 else{
    73 result=0;
    74 }
    75 return result;
    76 }
    77 
    78 }
    View Code

    第三种:用list的子类:Vector、ArrayList存放对象们,调用Collections.sort(list,comparator)方法进行排序。

     1 public class CollectionsTest {
     2 
     3 public static void main(String[] args) {
     4 Vector<Person> people=new Vector<>();//用向量保存对象
     5 
     6 //ArrayList<Person> people=new ArrayList<>()://用ArrayList保存对象。
     7 people.add(new Person("小明", 20));
     8 people.add(new Person("小张", 30));
     9 people.add(new Person("小刘", 18));
    10 people.add(new Person("小林", 17));
    11 people.add(new Person("小刘", 35));
    12 Collections.sort(people,new MyComparator());//调用方法进行排序
    13 Iterator it=people.iterator();
    14 while(it.hasNext()){
    15 System.out.println(it.next());
    16 }
    17 }
    18 
    19 }
    20 class Person {
    21 
    22 String name;
    23 int age;
    24 
    25 public Person() {
    26 }
    27 
    28 public Person(String name, int age) {
    29 this.name = name;
    30 this.age = age;
    31 }
    32 
    33 public String toString(){
    34 return "姓名:"+name+",年龄:"+age;
    35 }
    36 
    37 }
    38 class MyComparator implements Comparator<Person>{//实现Comparator接口,自定义比较器,实现compare方法定义比较算法
    39 
    40 /*
    41 compare(o1,o2):方法传进两个对象,根据某属性进行比较,返回一个int值。
    42 int>0,o1排在o2后;
    43 int<0,o1排在o2前;
    44 int=0,维持原来存放时的相对位置。
    45 
    46 */
    47 public int compare(Person p1, Person p2) {
    48 int result=p1.age<p2.age?1:(p1.age==p2.age?0:-1);//降序排列
    49 //int result=p1.age<p2.age?1:(p1.age==p2.age?0:-1);//升序排列
    50 
    51 if(result==0){
    52 result=p1.name.compareTo(p2.name);
    53 }
    54 return result;
    55 }
    56 
    57 }
    View Code
  • 相关阅读:
    [Canvas]英雄可以射箭了
    [Canvas]人物型英雄出现(前作仅为箭头)
    day33_Spring学习回顾_01
    day33_Spring学习笔记_01
    MyEclipse中,当我们写一个类实现一个接口时,会自动生成重写该接口的方法,但是,方法的参数提示不够好,是什么原因导致的呢?该如何解决呢?
    使用Junit测试一个 spring静态工厂实例化bean 的例子,所有代码都没有问题,但是出现java.lang.IllegalArgumentException异常
    MyEclipse中如何变换查看项目文件夹
    实战网卡bond
    Centos7上使用官方YUM源安装Mysql
    CentOS 7上安装WordPress详细步骤
  • 原文地址:https://www.cnblogs.com/huangdabing/p/9249240.html
Copyright © 2020-2023  润新知