2017-09-04 3 views
4

PersonとPersonというクラスがあり、名前、年齢帯などの詳細があります。
年齢間隔は{0-5、6-10、11-30、31-45、46-50、50-100、100-110}です。Javaで数値の文字列の間隔を並べ替える

私は、nameageBandの文字列間隔を持つPersonクラスを持っています。これはパラメータ化されたコンストラクタ、getters、settersです。

class TestAgeBand { 
    public static void main(String args[]) { 
     ArrayList<Person> person = new ArrayList<Person>(); 

     Person p1 = new Person("Mike1", "0-5"); 
     Person p2 = new Person("Mike2", "6-10"); 
     Person p3 = new Person("Mike3", "11-30"); 
     Person p4 = new Person("Mike4", "31-45"); 
     Person p5 = new Person("Mike5", "50-100"); 
     Person p6 = new Person("Mike6", "46-50"); 
     Person p7 = new Person("Mike7", "100-110"); 

     person.add(p1); 
     //adding all persons to list. 
    } 
} 

class Person { 
    String name; 
    String ageBand; //say it is string "0-50" which i pass in constructor while creating a person. 
    //getters 
    //setters 
} 

は、ここで私は間隔をソートする私のコードでやっているものです。 私は、間隔をあけて人を並べ替える必要があります。 私はTreemapを使って区間をソートしています。

Map<String, Person> ageBandMap = new TreeMap<String, Person>(){ 
    for(Person p: person) { 
     ageBandMap.put(p.ageBand, p.name); 
    } 
} 

私は間隔キーセットを印刷するとき、私が取得

出力:

[0-5、100-110、11-30、31-45、46-50、50- 100,6-10]

これは私が必要としないものです。

[0-5、6-10、11-30、31-45、46-50、50-100、100-110]

+2

コードのコメントから出て、それがために値する問題に重要な非コード情報のほとんどを取得してください。 –

+2

年齢の範囲を2つのフィールドに分割したい場合があります。次に比較するのが簡単です。 –

+2

実際、@MuratKとは何ですか?そしてそれらを両方とも***の***、すなわち 'int'フィールドにします。 int表現ではなく、数値の文字列表現をソートしようとしています。 –

答えて

3

てみ分裂:私はこのようなソートされた間隔を必要としますageBand文字列をIntegerに変換すると、並べ替えが容易になります。

person.stream().sorted(Comparator.comparing(element -> Integer.parseInt(element.getAgeBand().split("-")[0]))) 
      .collect(Collectors.toList()); 

あなたがJava 8を使用したくない場合は、Collections.sort()方法でそれを行うことができます。

Collections.sort(person, new Comparator<Person>() { 
     @Override 
     public int compare(Person o1, Person o2) { 
      return Integer.parseInt(o1.getAgeBand().split("-")[0]) - Integer.parseInt(o2.getAgeBand().split("-")[0]); 
     } 
    }); 
+0

私はjava8構文の知識がありません。それがjava7構文であれば役立ちます。 –

+0

正しい比較を行うには、バンドのsecons部分のために 'thenComparing'が必要です。 –

+0

あなたのソリューションは私の時間を節約しました。ありがとうございました。 –

2

我々はここで本当に賢いことをしようとし、そして実際の範囲を比較しTreeMapにカスタムコンパレータを渡すことができ。しかし、範囲が完全にオーバーラップしていないので、それぞれの範囲の下位(または上位)の値を使用してPersonを表すだけで、同じ並べ替え効果を得ることができます。したがって、私は次のことをお勧め:

public class Person { 
    String name; 
    Integer lower; 
    Integer upper; 
} 

SortedSet<Person> set = 
    new TreeSet<Person>(new Comparator<Person>() 
    { 
     public int compare(Person p1, Person p2) { 
      if (p1 == null && p2 == null) return 0; 
      if (p1 == null) return -1; 
      if (p2 == null) return 1; 
      return p1.getLower().compareTo(p2.getLower()); 
     } 
    }); 
0

あなたは、キーの値にあなたは彼らがあなたがLinkedHashMapを使用することができ、プリントアウトしたいの方法を置く場合 - 順序を置く覚えています。

0

インターフェイスに抽象化間隔に必要があります。その後、

interface Interval extends Comparable { 

    int left(); 
    int right(); 
} 

public final class IntervalImpl implements Interval { 

    private final int left; 
    private final int right; 


    public IntervalImpl(int left, int right) { 
      this.left = left; 
      this.right = right; 
    } 

    public IntervalImpl(String interval) { 
      this.left = Integer.parseInt(interval.split("-")[0]); 
      this.right = Integer.parseInt(interval.split("-")[1]); 
    } 

    @Override 
    public int left() { return left; } 

    @Override 
    int right() { return right; } 

    @Override 
    int compareTo(Interval other) { 
     return left.compareTo(other.left()); 
    } 

} 

そして、あなたの人のクラスでそれを使用します。

public final class Person { 
    private final Interval interval; 
    private final String name; 

    public Person (String name, String interval) { 
      this.name = name; 
      this.interval = new Interval(interval); 
    } 

    public Interval getInterval() { 
      return interval; 
    } 
} 

そしてマップでそれを使用します。

Map<Interval, Person> map = new TreeMap<>(); 

私はあなたの間隔の定数をEnumに移動することを提案します。あなたのInterval抽象化の中でそれを作った。

+0

私は 'IntervalImpl'の名前の選択を除いて、このアプローチが気に入っています。これは、これが「インターバル」の唯一の実装であることを示唆しています。そのインタフェースが1つの実装のみを持つように設計されている場合、それを具体的なクラスにするのはなぜですか?それが複数の実装を持つことができるなら、 'IntervalImpl'という名前は、その特定の実装を特徴付けるものを述べなければなりません。 –

+0

@KlitosKyriacouは、このようなインターフェースを備えていますが、これは唯一の実装でもあります。他のint型のコンテナを実装する方法は他にありますか? –

+0

1つの実装にしか見えないかもしれません。しかし、あなたは日付の間隔や他の何かを持つことができます。より多くのロジックを持つことができるだけでなく、 "intのペアのコンテナ"であることができます。はい、好きなように名前を変更できます。 –

0

は、ここでのコードは、あなたがしたいスニペットです:

Map<String,Person> ageBandMap = new LinkedHashMap<>(); 
    Map<Integer, Person> ageBandIntMap = new TreeMap<>(); 

    for(Person p: person) 
     ageBandIntMap.put(Integer.parseInt(p.ageBand.split("-")[0]), p); 

    for(Entry<Integer, Person> entry : ageBandIntMap.entrySet()) 
     ageBandMap.put(entry.getValue().ageBand, entry.getValue()); 

    for(Entry<String, Person> entry : ageBandMap.entrySet()) 
     System.out.format("\nageBand : %7s\t Person name : %S", entry.getKey(), entry.getValue().name); 
関連する問題