2017-08-19 15 views
4

私はJava 8を初めて使用しています。名前で並べ替えるだけです。しかし、条件は:重複する名前がある場合は、年齢に応じてソートする必要があります。Javaで年齢とともに名前を並べ替える方法

例えば、私の入力は

tarun 28 
arun 29 
varun 12 
arun 22 

で、出力は

arun 22 
arun 29 
tarun 28 
varun 12 

でなければなりません。しかし、私は

varun 12 
arun 22 
tarun 28 
arun 29 

のようなものを取得し、それがどちらかだけの年齢や名前でソートを意味します。

これが実装されているコードです:

POJOクラス:

class Person { 

    String fname; 

    int age; 

    public Person() { 
    } 

    public int getAge() { 
     return age; 
    } 

    public void setAge(int age) { 
     this.age = age; 
    } 

    public String getFname() { 
     return fname; 
    } 

    public void setFname(String fname) { 
     this.fname = fname; 
    } 

    public Person(String fname, int age) { 
     this.fname = fname; 

     this.age = age; 
    } 

    @Override 
    public String toString() { 
     return fname + age; 
    } 
} 

Testクラス:

public class Test { 

    public static void main(String[] args) { 
     List<Person> persons = new ArrayList<>(); 
     persons.add(new Person("tarun", 28)); 
     persons.add(new Person("arun", 29)); 
     persons.add(new Person("varun", 12)); 
     persons.add(new Person("arun", 22)); 

     Collections.sort(persons, new Comparator<Person>() { 

      @Override 
      public int compare(Person t, Person t1) { 
       return t.getAge() - t1.getAge(); 
      } 
     }); 
     System.out.println(persons); 

    } 
} 

答えて

4

現在、あなたはa)1つの属性だけを比較し、b)Java 8の新しい機能を実際には使用していません。

あなたは、このような method referencesとチェーンコンパレータ、使用できるJava 8で

:これは彼らのfnameとすることにより、第1 2つのPersonインスタンスを比較します

Collections.sort(persons, Comparator.comparing(Person::getFname) 
    .thenComparingInt(Person::getAge)); 

を - それが等しい場合 - そのageで(わずかに最適化ボクシングを避けるためにthenComparingIntに)。

+0

驚くほどのお礼。 –

3

あなたは正しい道にありますが、あなたのcompare方法が不完全です。

compareは、各ペアのどのアイテムが他のアイテムの前に行くかを決定するために呼び出されるため、タイブレークワン以外のすべての比較ロジックを含める必要があります。あなたのコードは名前だけを無視して、年齢だけで並べ替えます。

ロジックは次のように行く必要があります。名前はない同じであれば

  • t.getFname().compareTo(t1.getFname())
  • を使用して名前を比較、年齢を比較した結果を返し、そうでない場合と比較
  • の結果を返します。

整数を比較する適切な方法は、静的Integer.compareメソッド(つまり、Integer.compare(t.getAge(), t1.getAge()))です。

2

最初に名前を比較する必要があります。 名前が同じであれば、とだけにして、結果を使用すると、昇順から降順に変更したい場合は、単に符号を変える年齢

public static void main(String[] args) { 
    List<Person> persons = new ArrayList<>(); 
    persons.add(new Person("tarun", 28)); 
    persons.add(new Person("arun", 29)); 
    persons.add(new Person("varun", 12)); 
    persons.add(new Person("arun", 22)); 

    Collections.sort(persons, new Comparator<Person>() { 

     public int compare(Person t, Person t1) { 
      int comp = t.getFname().compareTo(t1.getFname()); 
      if (comp != 0) { // names are different 
       return comp; 
      } 
      return t.getAge() - t1.getAge(); 
     } 
    }); 
    System.out.println(persons); 

}} 

を比較することに依存しています。例えば

return -comp; 

や人

名をスワップ

int comp = t1.getFname().compareTo(t.getFname()); 

年齢

return t1.getAge() - t.getAge(); 
1

あなたComparatorは年齢別ではなく、名前でソートされます。

あなたはそのようにそれを試みることができる:

new Comparator<Person>() { 
    @Override 
    public int compare(Person t, Person t1) { 
     int ret = t.getFname().compareTo(t1.getFname()); 
     if (ret == 0) { 
      ret = Integer.compare(t.getAge(), t1.getAge()); 
     } 
     return ret; 
    } 
} 

あなたはまた、Personクラス自体にComparable<Person>を実装について考えることができます:

class Person implements Comparable<Person> { 
    @Override 
    public int compareTo(Person p) { 
     int ret = fname.compareTo(p.fname); 
     if (ret == 0) { 
      ret = Integer.compare(age, p.getAge()); 
     } 
     return ret; 

    } 
} 
0

これがために三項演算子を使って、簡単な1つのライナー比較でありますオブジェクトをソートする。 多くのif/elseブロックを書く必要はありません。

Collections.sort(persons, new Comparator<Person>() { 

    @Override 
    public int compare(Person t1, Person t2) { 

     return t1.getFname().equals(t2.getFname()) ? t1.getAge()-t2.getAge() : t1.getFname().compareTo(t2.getFname()); 

    } 
}); 
関連する問題