问题:某班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;     
      
  } 
    
}
输出结果如图:
对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)set14b2ea0061b0064854e2015e9f0ccaf9 keyset:将map中所有的键存入到set集合。因为set具备迭代器。所有可以迭代方式取出所有的键,在根据get方法。获取每一个键对应的值。
(2)setf7c0dd2036bac3679cff141deb226d10> entryset:将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:map.entry
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
更多一道java集合框架题 多种解题思路。
   
 
   