问题:某班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)Set<k> keySet:将map中所有的键存入到Set集合。因为set具备迭代器。

所有可以迭代方式取出所有的键,在根据get方法。获取每一个键对应的值。

(2)Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到了set集合中,

而这个关系的数据类型就是:Map.Entry

一道Java集合框架题的更多相关文章

  1. Java集合框架 10 连问,你有被问过吗?

    首先要说一下,本文对这些Java集合框架的面试题只做了一个总结式的回答,对每一道题目,都值得深入去了解一下(什么是扎实基本功,这些就是基本功~~),后续可能对每一道题目拆开独立篇章来深入讲解一下. 大 ...

  2. (未完)Java集合框架梳理(基于JDK1.8)

    Java集合类主要由两个接口Collection和Map派生出来的,Collection派生出了三个子接口:List.Set.Queue(Java5新增的队列),因此Java集合大致也可分成List. ...

  3. Java中的函数式编程(五)Java集合框架中的高阶函数

    写在前面 随着Java 8引入了函数式接口和lambda表达式,Java 8中的集合框架(Java Collections Framework, JCF)也增加相应的接口以适应函数式编程.   本文的 ...

  4. Java集合框架List,Map,Set等全面介绍

    Java集合框架的基本接口/类层次结构: java.util.Collection [I]+--java.util.List [I]   +--java.util.ArrayList [C]   +- ...

  5. Java集合框架练习-计算表达式的值

    最近在看<算法>这本书,正好看到一个计算表达式的问题,于是就打算写一下,也正好熟悉一下Java集合框架的使用,大致测试了一下,没啥问题. import java.util.*; /* * ...

  6. 【集合框架】Java集合框架综述

    一.前言 现笔者打算做关于Java集合框架的教程,具体是打算分析Java源码,因为平时在写程序的过程中用Java集合特别频繁,但是对于里面一些具体的原理还没有进行很好的梳理,所以拟从源码的角度去熟悉梳 ...

  7. Java 集合框架

    Java集合框架大致可以分为五个部分:List列表,Set集合.Map映射.迭代器.工具类 List 接口通常表示一个列表(数组.队列.链表 栈),其中的元素 可以重复 的是:ArrayList 和L ...

  8. Java集合框架之map

    Java集合框架之map. Map的主要实现类有HashMap,LinkedHashMap,TreeMap,等等.具体可参阅API文档. 其中HashMap是无序排序. LinkedHashMap是自 ...

  9. 22章、Java集合框架习题

    1.描述Java集合框架.列出接口.便利抽象类和具体类. Java集合框架支持2种容器:(1) 集合(Collection),存储元素集合 (2)图(Map),存储键值对.

随机推荐

  1. Vue.js 60分钟快速入门

    原文链接:http://www.cnblogs.com/keepfool/p/5619070.html Vue.js介绍 Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和 ...

  2. P3240 [HNOI2015]实验比较 树形DP

    \(\color{#0066ff}{ 题目描述 }\) 小D 被邀请到实验室,做一个跟图片质量评价相关的主观实验.实验用到的图片集一共有 \(N\) 张图片,编号为 \(1\) 到\(N\).实验分若 ...

  3. tinkphp中的自动验证

    tinkphp是国内非常流行的一个开源框架,国内大小公司都在用的框架.对于初学的好多同学感觉不太好上手,其实并没没有大家想的那么复杂.自动验证功能是thinkphp提高的一种数据验证方法,分为动态和静 ...

  4. Qt 学习之路 2(9):资源文件

    Qt 学习之路 2(9):资源文件  豆子  2012年8月31日  Qt 学习之路 2  62条评论 上一章节中我们介绍了如何使用QAction添加动作.其中,我们使用QIcon加载了一张 png ...

  5. Nginx根据目录自动生成二级域名

    前言:     每次创建二级域名如果都修改一次配置文件的话,项目多了会带来很多不必要的工作量,如果能够在一个web目录下创建一个文件夹并且自动生成文件目录的话,那真是极好的,本文就基于Nginx贴出这 ...

  6. redis安装及应用

    Redis安装及主从配置 server2,3,4. 安装 tar zxf redis-4.0.1.tar.gz cd redis-4.0.1 yum install -y gcc make make ...

  7. Spring boot的热部署

    当把配置文件,比如yml也打到jar包后,如何修改配置,而又不用重新发布呢? 在jar包同一目录下,放置Application.yml (注意,不管jar包内是否此文件名)修改配置文件后,重新启动ja ...

  8. hive 取两次记录的时间差 lead lag first_value last_value

    -- LEAD(col,n,DEFAULT) 用于统计窗口内往下第n行值 -- 第一个参数为列名,第二个参数为往下第n行(可选,默认为1),第三个参数为默认值(当往下第n行为NULL时候,取默认值,如 ...

  9. java——HashMap、Hashtable

    Map:类似Python的字典 HashMap: 不支持线程的同步,即同一时刻不能有多个线程同时写HashMap: 最多只允许一条记录的键值为null,不允许多条记录的值为null HashMap遍历 ...

  10. Vue.js-----轻量高效的MVVM框架(八、使用组件)

    什么是组件? 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能.在有 ...