一道Java集合框架題 多種解題思路
問題:某班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;
}
}
//創(chuàng)建一個比較器類
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集合其實是一個動態(tài)的數組,元素可以直接通過for循環(huán)取出,而不需要迭代。
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 比較器類())方法。所以需要自定義一個比較器類,定義自己的比較規(guī)則。
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)));
}
//迭代循環(huán)取出
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)方法,在其中定義比較規(guī)則。
(2)讓元素自身具備比較性。
步驟:將add進TreeSet中的元素實現Comparable接口,并且覆蓋compareTo方法。這種順序也是元素的自然順序,或者叫做默認順序。
方法1和方法2的區(qū)別:
兩種方法各有優(yōu)劣, 用Comparable 簡單, 只要實現Comparable 接口的對象直接就成為一個可以比較的對象,但是需要修改源代碼。
用Comparator 的好處是不需要修改源代碼, 而是另外實現一個比較器, 當某個自定義的對象需要作比較的時候,把比較器和對象一起傳遞過去就可以比大小了, 并且在Comparator 里面用戶可以自己實現復雜的可以通用的邏輯,使其可以匹配一些比較簡單的對象,那樣就可以節(jié)省很多重復勞動了。
(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.創(chuàng)建集合
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
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
SpringBoot+SpringCache實現兩級緩存(Redis+Caffeine)
這篇文章主要介紹了SpringBoot+SpringCache實現兩級緩存(Redis+Caffeine),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-04-04
Java 動態(tài)模擬操作系統(tǒng)進程調度算法
這篇文章主要介紹了采用java語言編程模擬N個進程采用動態(tài)高優(yōu)先權優(yōu)先進程調度算法。文中代碼具有一定的學習價值,感興趣的小伙伴可以了解一下2021-12-12
SpringBoot Devtools實現項目熱部署的方法示例
這篇文章主要介紹了SpringBoot Devtools實現項目熱部署的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-01-01
mybatis注解之@Mapper和@MapperScan的使用
這篇文章主要介紹了mybatis注解之@Mapper和@MapperScan的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10

