English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

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; 
  } 
} 
//比較器クラスを作成します 
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 implements Comparator{ } 、compare(Object o1, Object o2)メソッド内で比較規則を定義します。
(2)要素自身に比較性を与えます。
手順:TreeSetにaddされた要素が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のまとめ:
1HashSetの要素は重複できません。重複して追加すると、表示されるのは1つだけです。
原理は以下の通りです:
HashSet:ベースデータ構造はハッシュテーブルです。スレッドセーフではありません。同期されていません。
2HashSetはどのように要素のユニーク性を保証しているのでしょうか?
答:要素の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 はデフォルトでキーをソートするため、カスタムオブジェクトをキーに置くことができ、学籍番号を表す整型を値に置くことができます。キーのソート時に、カスタムオブジェクトの特定の属性を指定してソートすることができます。
2、Map 集合を使用して put()メソッドで要素を追加します。
3、Map 集合の取得原理:map 集合を set 集合に変換し、イテレータを使用して取得します。map 集合の取得方法の2種類:
(1)Set<k> keySet:map 中のすべてのキーを set 集合に保存します。なぜなら、set にはイテレータが存在するため、すべてのキーをイテレートして、get メソッドを使用して各キーに対応する値を取得できます。
(2)Set<Map.Entry<k,v>> entrySet:map 集合のマッピング関係を set 集合に保存し、その関係のデータ型は:Map.Entry です。

これで本文の全てが終わりです。皆様の学習に役立つことを願っています。また、呐喊教程を多くの皆様にサポートしていただけると嬉しいです。

声明:本文の内容はインターネットから取得しており、著作権者は所有しておりません。インターネットユーザーが自発的に貢献し、自己でアップロードした内容であり、本サイトは所有権を持ちません。また、人工編集は行われていません。著作権侵害が疑われる内容がある場合は、メールを送信していただければ幸いです:notice#oldtoolbag.com(メールを送信する際、#を@に置き換えてください。報告を行い、関連する証拠を提供してください。一旦確認が取れた場合、本サイトは即座に侵害疑いの内容を削除します。)

おすすめ