• 技术文章 >Java >java教程

    一道Java集合框架题 多种解题思路

    高洛峰高洛峰2017-01-23 16:57:17原创803
    问题:某班30个学生的学号为20070301-20070330,全部选修了Java程序设计课程,给出所有同学的成绩(可用随机数产生,范围60-100),请编写程序将本班各位同学的成绩按照从低到高排序打印输出。

    要求:分别用List、Map、Set来实现,打印的信息包括学号、姓名和成绩。

    1、使用List集合来实现

    import java.util.ArrayList; 
    import java.util.Collections; 
    import java.util.Comparator; 
    import java.util.Iterator; 
    import java.util.LinkedList; 
    import java.util.TreeMap; 
      
      
      
    public class Test2{ 
        
      public static void main(String[] args){ 
          
        /* 此处用ArrayList实现 
         * 
         * ArrayList<Student>al=new ArrayList<Student>(); 
        for(int i=20070301,j=10;i<=20070330;i++,j++) 
        { 
          al.add(new Student(i,(int) (40*Math.random()+60), "同学"+j)); 
        } 
          
        //ArrayList排序借助Collections中的sort()方法实现。 
        Collections.sort(al, new Sortbygrade()); 
        for(Student sd:al) 
        System.out.println(sd); 
          
        */
          
        LinkedList<Student> lt=new LinkedList<Student>(); 
        for(int i=20070301,j=10;i<=20070330;i++,j++) 
        { 
          lt.add(new Student(i,(int) (40*Math.random()+60), "同学"+j)); 
        } 
          
        //对链表排序 
        Collections.sort(lt, new Sortbygrade()); 
        //输出链表 
        for(Student sd:lt) 
          System.out.println(sd); 
          
      } 
        
    } 
      
      
      
    //学生类 
    class Student{ 
      int num,grade; 
      String name; 
        
      //构造函数 
      public Student(int num,int grade,String name){ 
          
        this.num=num; 
        this.name=name; 
        this.grade=grade; 
      } 
        
      //此处必须覆写 
      public String toString(){ 
    //   System.out.println("hi"); 
        return "学号:"+this.num+"\t"+"姓名:"+this.name+"  "+"成绩:"+this.grade; 
      } 
        
    } 
      
    //创建一个比较器类 
    class Sortbygrade implements Comparator<Student>{ 
      
      @Override
      public int compare(Student s1, Student s2) { 
          
        if(s1.grade>s2.grade) 
          return 1; 
        if(s1.grade<s2.grade) 
          return -1; 
        if(s1.grade==s2.grade) 
          return s1.name.compareTo(s2.name); 
        return 0;     
          
      } 
        
    }

    输出结果如图:

    一道Java集合框架题 多种解题思路

    对List集合框架的总结:

    1、List集合其实是一个动态的数组,元素可以直接通过for循环取出,而不需要迭代。
    2、输出List集合时,会默认调用集合中存储对象的toString()方法,所以在类中需要进行覆写。
    若不覆写toString( )方法,则必须使用

    for(int i=0;i<lt.size();i++)
    {
      Student s=lt.get(i);
      System.out.println("学号:"+s.num+"  姓名:"+s.name+"  成绩:"+s.grade);
    }

    3、List集合的排序需要借助于Collections工具类,即Collections.Sort(list,new 比较器类())方法。所以需要自定义一个比较器类,定义自己的比较规则。

    2、使用Set集合来实现
    (1)使用TreeSet来实现

    package com.package1;
      
    import java.util.*;
      
    public class StuScore {
      
    public static void main(String[] args) {
      
      TreeSet<Student> ts=new TreeSet<Student>(new Com());
      //添加元素进去
      for(int i=20070301,j=1;i<=20070330;i++,j++)
      {
        ts.add(new Student(i,"同学"+j,(int) (40*Math.random()+60)));
      }
      
      //迭代循环取出
      Iterator<Student> it=ts.iterator();
      while(it.hasNext())
      {
        Student o1=it.next();
        System.out.println("学号:"+o1.num+" "+"姓名:"+o1.name+" "+" "+"成绩:"+o1.grade);
      
      }
      
    }
    }
    //学生类
    class Student 
    {
    int num;
    int grade;
    String name;
      
      
    public Student(int num, String name,int grade)
    {
      this.num=num;
      this.name=name;
      this.grade=grade;
    }
    }
    class Com implements Comparator
    {
      
    @Override
    public int compare(Object o1, Object o2) {
      
      Student s1=(Student) o1;
      Student s2=(Student) o2;
      if(s1.grade>s2.grade)
        return 1;
      if(s1.grade<s2.grade)
        return -1;
      if(s1.grade==s2.grade)
      {
        return new Integer(s1.num).compareTo(new Integer(s2.num));
      }
      return 0;
    }
    }

    输出结果为:

    学号:20070307 姓名:同学16 成绩:60
    学号:20070309 姓名:同学18 成绩:60
    学号:20070314 姓名:同学23 成绩:61
    学号:20070318 姓名:同学27 成绩:61
    学号:20070322 姓名:同学31 成绩:61
    学号:20070306 姓名:同学15 成绩:62
    学号:20070310 姓名:同学19 成绩:64
    学号:20070302 姓名:同学11 成绩:66
    学号:20070308 姓名:同学17 成绩:68
    学号:20070321 姓名:同学30 成绩:68
    学号:20070330 姓名:同学39 成绩:69
    学号:20070303 姓名:同学12 成绩:70
    学号:20070320 姓名:同学29 成绩:70
    学号:20070323 姓名:同学32 成绩:77
    学号:20070313 姓名:同学22 成绩:78
    学号:20070304 姓名:同学13 成绩:79
    学号:20070324 姓名:同学33 成绩:83
    学号:20070326 姓名:同学35 成绩:84
    学号:20070327 姓名:同学36 成绩:85
    学号:20070311 姓名:同学20 成绩:88
    学号:20070305 姓名:同学14 成绩:89
    学号:20070329 姓名:同学38 成绩:89
    学号:20070316 姓名:同学25 成绩:90
    学号:20070301 姓名:同学10 成绩:95
    学号:20070312 姓名:同学21 成绩:96
    学号:20070317 姓名:同学26 成绩:97
    学号:20070319 姓名:同学28 成绩:97
    学号:20070325 姓名:同学34 成绩:98
    学号:20070315 姓名:同学24 成绩:99
    学号:20070328 姓名:同学37 成绩:99

    对TreeSet的总结:
    1、元素不可以重复,而且TreeSet是有序的。
    2、两种排序方法:
    (1)自定义一个比较器类,比如class Com implementsComparator{ } ,实现compare(Object o1, Object o2)方法,在其中定义比较规则。
    (2)让元素自身具备比较性。
    步骤:将add进TreeSet中的元素实现Comparable接口,并且覆盖compareTo方法。这种顺序也是元素的自然顺序,或者叫做默认顺序。

    方法1和方法2的区别:

    两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码。

    用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。

    (2)使用HashSet来实现

    package com.package1;
      
    import java.util.*;
      
      
      
      
    public class StuScore {
      
      public static void main(String[] args) {
          
        HashSet<Student> hs=new HashSet<Student>();
        //添加元素进去
        for(int i=20070301,j=1;i<=20070330;i++,j++)
        {
          
          hs.add(new Student(i,"同学"+j,(int) 
      
    (40*Math.random()+60)));
        }
          
        ArrayList<Student>li=new ArrayList(hs);
          
        Collections.sort(li, new Sortbygrade());
          
        for(Student ss:li)
          System.out.println(ss);
          
      
      }
      
    }
    //学生类
    class Student 
    {
      int num;
      int grade;
      String name;
      
        
      public Student(int num, String name, int grade)
      {
        this.num=num;
        this.name=name;
        this.grade=grade;
      }
      public String toString(){
        //System.out.println("hi");
        return "学号:"+this.num+"\t"+"姓名:"+this.name
      
    +"  "+"成绩:"+this.grade;
      }
        
        
    }
      
      
    class Sortbygrade implements Comparator{
      
      @Override
      public int compare(Object o1, Object o2) {
          
        Student s1=(Student) o1;
        Student s2=(Student) o2;
        if(s1.grade>s2.grade)
          return 1;
        if(s1.grade<s2.grade)
          return -1;
    //   if(s1.grade==s2.grade)
          
        return 0;
      }
        
    }

    输出结果如下:
    学号:20070310 姓名:同学19 成绩:60
    学号:20070330 姓名:同学39 成绩:62
    学号:20070326 姓名:同学35 成绩:63
    学号:20070317 姓名:同学26 成绩:64
    学号:20070318 姓名:同学27 成绩:65
    学号:20070322 姓名:同学31 成绩:65
    学号:20070301 姓名:同学10 成绩:67
    学号:20070328 姓名:同学37 成绩:68
    学号:20070304 姓名:同学13 成绩:68
    学号:20070319 姓名:同学28 成绩:69
    学号:20070313 姓名:同学22 成绩:70
    学号:20070303 姓名:同学12 成绩:71
    学号:20070312 姓名:同学21 成绩:71
    学号:20070329 姓名:同学38 成绩:72
    学号:20070306 姓名:同学15 成绩:72
    学号:20070324 姓名:同学33 成绩:72
    学号:20070305 姓名:同学14 成绩:75
    学号:20070315 姓名:同学24 成绩:75
    学号:20070314 姓名:同学23 成绩:78
    学号:20070307 姓名:同学16 成绩:80
    学号:20070311 姓名:同学20 成绩:81
    学号:20070302 姓名:同学11 成绩:83
    学号:20070309 姓名:同学18 成绩:84
    学号:20070320 姓名:同学29 成绩:85
    学号:20070321 姓名:同学30 成绩:85
    学号:20070316 姓名:同学25 成绩:86
    学号:20070327 姓名:同学36 成绩:90
    学号:20070308 姓名:同学17 成绩:94
    学号:20070323 姓名:同学32 成绩:94
    学号:20070325 姓名:同学34 成绩:95

    对HashSet的总结:
    1、HashSet中的元素不可以重复,如果重复添加,则只会显示一个。
    原理如下:
    HashSet:底层数据结构是哈希表。是线程不安全的。不同步。
    2、HashSet是如何保证元素唯一性的呢?
    答:是通过元素的两个方法,hashCode和equals来完成。
    如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashcode值不同,不会调用equals。
    3、对HashSet的排序,通过将Set集合转化为List集合,借助Collections.Sort( )方法实现排序。

    3、使用TreeMap来实现

    package com.package1; 
      
    import java.util.Comparator;
    import java.util.Iterator;
    import java.util.Set;
    import java.util.TreeMap;
      
    public class TestTreeMap {
      
      public static void main(String[] args) {
        //1.创建集合
        TreeMap<Student,Integer> tm=new TreeMap<Student,Integer>();
        for(int i=20070301,j=10;i<=20070330;i++,j++)
        {
          int grade=(int) (40*Math.random()+60);
           //2、往集合对象中添加元素
           tm.put(new Student(grade,"同学"+j),i);
        }
          
        //3.遍历集合 ,排序完成 
        Set<Student> k=tm.keySet();
        Iterator<Student> it=k.iterator();
          
        while(it.hasNext()){
          Student key=it.next();
          Integer num=tm.get(key);
            
          System.out.println("学号:"+num+"  "+"姓名:"+key.name+"  "+"成绩:"+key.grade);
        }
      }
      
    }
      
    class Student implements Comparable<Student>{
      int grade;
      String name;
        
      public Student(int grade,String name){
        this.grade =grade;
        this.name=name;
      }
      
      @Override
      public int compareTo(Student o) {
          
        if(this.grade>o.grade) 
          return 1; 
          if(this.grade==o.grade) 
          { //当成绩相同时,按照姓名排序
           return this.name.compareTo(o.name); 
          } 
          return -1; 
      
      }
        
      
        
    }

    输出结果为:

    学号:20070303 姓名:同学12 成绩:61
    学号:20070323 姓名:同学32 成绩:61
    学号:20070317 姓名:同学26 成绩:62
    学号:20070309 姓名:同学18 成绩:64
    学号:20070301 姓名:同学10 成绩:67
    学号:20070304 姓名:同学13 成绩:69
    学号:20070322 姓名:同学31 成绩:69
    学号:20070328 姓名:同学37 成绩:70
    学号:20070305 姓名:同学14 成绩:71
    学号:20070319 姓名:同学28 成绩:73
    学号:20070321 姓名:同学30 成绩:74
    学号:20070310 姓名:同学19 成绩:81
    学号:20070315 姓名:同学24 成绩:82
    学号:20070307 姓名:同学16 成绩:84
    学号:20070330 姓名:同学39 成绩:84
    学号:20070312 姓名:同学21 成绩:85
    学号:20070324 姓名:同学33 成绩:87
    学号:20070306 姓名:同学15 成绩:88
    学号:20070308 姓名:同学17 成绩:90
    学号:20070327 姓名:同学36 成绩:90
    学号:20070318 姓名:同学27 成绩:91
    学号:20070316 姓名:同学25 成绩:92
    学号:20070320 姓名:同学29 成绩:92
    学号:20070314 姓名:同学23 成绩:93
    学号:20070313 姓名:同学22 成绩:94
    学号:20070302 姓名:同学11 成绩:95
    学号:20070325 姓名:同学34 成绩:95
    学号:20070329 姓名:同学38 成绩:97
    学号:20070326 姓名:同学35 成绩:98
    学号:20070311 姓名:同学20 成绩:99

    对TreeMap的总结:
    1、TreeMap默认对key进行排序,所以可将自定义对象放入key中,将代表学号的整型放入value中。对Key排序时,可以指定自定义对象中的某个属性来排序。
    2、Map集合使用put()方法添加元素。
    3、Map集合的取出原理:将map集合转成set集合。在通过迭代器取出。map集合的两种取出方式:
    (1)Set<k> keySet:将map中所有的键存入到Set集合。因为set具备迭代器。所有可以迭代方式取出所有的键,在根据get方法。获取每一个键对应的值。
    (2)Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:Map.Entry

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持PHP中文网。

    更多一道Java集合框架题 多种解题思路相关文章请关注PHP中文网!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:java 集合框架
    上一篇:JAVA collection集合之扑克牌游戏实例 下一篇:Java集合Iterator迭代的实现方法
    20期PHP线上班

    相关文章推荐

    • 【活动】充值PHP中文网VIP即送云服务器• java的10种排序算法实例• 归纳整理Java线程面试题• Java归纳整理之IO流原理及流的分类• 实例介绍Java基于quasar实现协程池• 一文带你认识Java栈和队列
    1/1

    PHP中文网