কিছু সম্পত্তি দ্বারা অবজেক্টের তালিকা কীভাবে সাজানো যায়


145

আমার সাধারণ ক্লাস আছে

public class ActiveAlarm {
    public long timeStarted;
    public long timeEnded;
    private String name = "";
    private String description = "";
    private String event;
    private boolean live = false;
}

এবং List<ActiveAlarm>কন কিভাবে আরোহী ক্রম অনুসারে বাছাইtimeStarted , তারপরে timeEnded? কেউ সাহায্য করতে পারেন? আমি জেনেরিক অ্যালগরিদম এবং ওভারলোড অপারেটরের সাথে সি ++ তে জানি, তবে আমি জাভাতে নতুন।


এই পোস্টে @ যিশাইয়ের উত্তর কাস্টম্ট বাছাইয়ের জন্য গ্রুপের বাছাই (একাধিক যুক্তি) তুলনা শৃঙ্খলা ব্যবহারের জন্য এনামের মার্জিত ব্যবহার প্রদর্শন করে।
gunalmel

উত্তর:


140

হয় আলাদা ক্লাসে ActiveAlarmপ্রয়োগ Comparable<ActiveAlarm>বা বাস্তবায়ন করুন Comparator<ActiveAlarm>। তারপরে কল করুন:

Collections.sort(list);

অথবা

Collections.sort(list, comparator);

সাধারণভাবে, তা বাস্তবায়ন করার জন্য একটি ভাল ধারণা Comparable<T>যদি একটি একক "স্বাভাবিক" সাজানোর ক্রম আছে ... অন্যথায় (যদি আপনি ঘটতে একটি নির্দিষ্ট ক্রমে সাজাতে চান, কিন্তু সমানভাবে সহজে অন্য আরেকটির চাইতে পারেন) তা বাস্তবায়ন ভালো Comparator<T>। এই নির্দিষ্ট পরিস্থিতিটি যে কোনও পথেই যেতে পারে, সত্যি বলতে ... তবে আমি সম্ভবত আরও নমনীয় Comparator<T>বিকল্পের সাথে থাকি ।

সম্পাদনা: নমুনা বাস্তবায়ন:

public class AlarmByTimesComparer implements Comparator<ActiveAlarm> {
  @Override
  public int compare(ActiveAlarm x, ActiveAlarm y) {
    // TODO: Handle null x or y values
    int startComparison = compare(x.timeStarted, y.timeStarted);
    return startComparison != 0 ? startComparison
                                : compare(x.timeEnded, y.timeEnded);
  }

  // I don't know why this isn't in Long...
  private static int compare(long a, long b) {
    return a < b ? -1
         : a > b ? 1
         : 0;
  }
}

1
যে তুলনা () ফাংশন দীর্ঘায়িত হয় না কারণ বাস্তবায়ন আরও বেশি তুচ্ছ: ফিরে a - খ;
পেপারক্রেন

5
@ পেপারক্রেন: না, ওভারফ্লো কারণে এটি ব্যর্থ। বিবেচনা করুন a = Long.MIN_VALUE, b = 1
জন স্কিটি

3
এপিআই 19 হিসাবে (কিটকাট) লং এর এখন আছে.compare
মার্টিন মার্কনকিনি

123

ব্যবহার Comparator

উদাহরণ স্বরূপ:

class Score {

    private String name;
    private List<Integer> scores;
    // +accessor methods
}

    Collections.sort(scores, new Comparator<Score>() {

        public int compare(Score o1, Score o2) {
            // compare two instance of `Score` and return `int` as result.
            return o2.getScores().get(0).compareTo(o1.getScores().get(0));
        }
    });

জাভা 8 এর পরে, তুলনামূলক উদাহরণটি উপস্থাপন করতে আপনি কেবল ল্যাম্বডা এক্সপ্রেশন ব্যবহার করতে পারেন।

Collections.sort(scores, (s1, s2) -> { /* compute and return int */ });

1
কি করে compareTo()? এটা কোথা থেকে এসেছে? আমি এটি সংজ্ঞা দিতে হবে কোথায়?
আসকিয়ার

1
@Asqiir getScores()জন্য সংগ্রহকারী হয় scoresযা হয় List<Integer>। আপনি যখন getScores().get(0)একটি Integerজিনিস পেতে । Integerইতিমধ্যে compareTo(anotherInteger)পদ্ধতিটি কার্যকর করা হয়েছে, আপনাকে এটি সংজ্ঞায়িত করতে হবে না।
ওয়ালেন 9:58

(0) কী পাওয়া যায়?
আলী খাকি

1
ধন্যবাদ মোহন মত কাজ করে (আমি এটি .get (0) অংশ ব্যতীত ব্যবহার করি)। আমি অর্ডারটি কীভাবে বিপরীত করব?

53

জাভা 8 এবং উপরের উত্তর (ল্যাম্বডা এক্সপ্রেশন ব্যবহার করে)

জাভা 8-এ, এটিকে আরও সহজ করার জন্য ল্যাম্বদা এক্সপ্রেশনগুলি চালু করা হয়েছিল! এর সমস্ত স্ক্যাফোল্ডিংয়ের সাথে একটি তুলনামূলক () অবজেক্ট তৈরি করার পরিবর্তে আপনি এটিকে নিম্নরূপে সহজ করতে পারেন: (উদাহরণ হিসাবে আপনার বস্তুটি ব্যবহার করে)

Collections.sort(list, (ActiveAlarm a1, ActiveAlarm a2) -> a1.timeStarted-a2.timeStarted);

বা আরও ছোট:

Collections.sort(list, Comparator.comparingInt(ActiveAlarm ::getterMethod));

এই একটি বিবৃতি নিম্নলিখিত সমতুল্য:

Collections.sort(list, new Comparator<ActiveAlarm>() {
    @Override
    public int compare(ActiveAlarm a1, ActiveAlarm a2) {
        return a1.timeStarted - a2.timeStarted;
    }
});

ল্যাম্বডা এক্সপ্রেশনগুলি কেবলমাত্র কোডের প্রাসঙ্গিক অংশে রাখার প্রয়োজন হিসাবে ভাবুন: পদ্ধতির স্বাক্ষর এবং কী ফিরে আসে।

আপনার প্রশ্নের আর একটি অংশ ছিল একাধিক ক্ষেত্রের সাথে কীভাবে তুলনা করা যায়। লাম্বদা এক্সপ্রেশন দিয়ে তা করতে, আপনি .thenComparing()কার্যকরভাবে দুটি তুলনা একের সাথে একত্রিত করতে ফাংশনটি ব্যবহার করতে পারেন :

Collections.sort(list, (ActiveAlarm a1, ActiveAlarm a2) -> a1.timeStarted-a2.timeStarted             
       .thenComparing ((ActiveAlarm a1, ActiveAlarm a2) -> a1.timeEnded-a2.timeEnded)
);

উপরের কোডটি প্রথমে তালিকাটি বাছাই করবে timeStartedএবং তারপরে timeEnded(সেই সমস্ত রেকর্ডগুলির জন্য একই timeStarted)।

একটি সর্বশেষ নোট: 'দীর্ঘ' বা 'অন্তর্গত' আদিমদের তুলনা করা সহজ, আপনি কেবল একটির থেকে অন্যটি বিয়োগ করতে পারেন। আপনি যদি বস্তুর তুলনা করছেন ('লং' বা 'স্ট্রিং'), আমি আপনাকে তাদের বিল্ট-ইন তুলনা ব্যবহার করার পরামর্শ দিই। উদাহরণ:

Collections.sort(list, (ActiveAlarm a1, ActiveAlarm a2) -> a1.name.compareTo(a2.name) );

সম্পাদনা: আমাকে কাজ করতে নির্দেশ করার জন্য লুকাশ ইডারকে ধন্যবাদ .thenComparing()


4
আপনি নতুন জাভা 8 এপিআইয়ের প্রশংসা করতে পারেন Comparator.comparing().thenComparing()...
লুকাশ এডার

1
ফেরতের পার্থক্য সহ সতর্কতা অবলম্বন করুন। অতিরিক্ত প্রবাহের ক্ষেত্রে, আপনি ভুল ফলাফল পেতে পারেন।
krzychu

2
এটি আইএমএইচও হ'ল সহজ বাছাই পদ্ধতি, আবার ধরেই নেওয়া আপনার কোনও প্রাকৃতিক অর্ডার নেই। আপনাকে Collectionsআর কল করার দরকার নেই, আপনি সরাসরি তালিকায় কল করতে পারেন। উদাহরণস্বরূপ:myList.sort(Comparator.comparing(Address::getZipCode).thenComparing(Compartor.comparing(Address::getStreetName));
CeePlusPlus

20

আমরা দুটি পদ্ধতির একটিতে তালিকাটি বাছাই করতে পারি:

1. তুলনাকারী ব্যবহার করে : একাধিক স্থানে বাছাইয়ের যুক্তি ব্যবহার করার প্রয়োজন হলে আপনি যদি একা জায়গায় বাছাইয়ের যুক্তি ব্যবহার করতে চান তবে আপনি নীচে একটি বেনামে অভ্যন্তর শ্রেণি লিখতে পারেন, না হলে তুলনামূলকটি বের করে একাধিক জায়গায় ব্যবহার করতে পারেন

  Collections.sort(arrayList, new Comparator<ActiveAlarm>() {
        public int compare(ActiveAlarm o1, ActiveAlarm o2) {
            //Sorts by 'TimeStarted' property
            return o1.getTimeStarted()<o2.getTimeStarted()?-1:o1.getTimeStarted()>o2.getTimeStarted()?1:doSecodaryOrderSort(o1,o2);
        }

        //If 'TimeStarted' property is equal sorts by 'TimeEnded' property
        public int doSecodaryOrderSort(ActiveAlarm o1,ActiveAlarm o2) {
            return o1.getTimeEnded()<o2.getTimeEnded()?-1:o1.getTimeEnded()>o2.getTimeEnded()?1:0;
        }
    });

আমরা "লং" এর পরিবর্তে 'লং' ব্যবহার করতে পারলে আমরা বৈশিষ্ট্যগুলির নাল চেক করতে পারি।

২. তুলনীয় (প্রাকৃতিক অর্ডারিং) ব্যবহার করে : যদি সাজানো অ্যালগরিদম সর্বদা একটি সম্পত্তিতে লেগে থাকে: এমন একটি শ্রেণি লিখুন যা 'তুলনামূলক' প্রয়োগ করে এবং নীচে বর্ণিত হিসাবে 'তুলনামূলক' পদ্ধতিটি ওভাররাইড করবে

class ActiveAlarm implements Comparable<ActiveAlarm>{

public long timeStarted;
public long timeEnded;
private String name = "";
private String description = "";
private String event;
private boolean live = false;

public ActiveAlarm(long timeStarted,long timeEnded) {
    this.timeStarted=timeStarted;
    this.timeEnded=timeEnded;
}

public long getTimeStarted() {
    return timeStarted;
}

public long getTimeEnded() {
    return timeEnded;
}

public int compareTo(ActiveAlarm o) {
    return timeStarted<o.getTimeStarted()?-1:timeStarted>o.getTimeStarted()?1:doSecodaryOrderSort(o);
}

public int doSecodaryOrderSort(ActiveAlarm o) {
    return timeEnded<o.getTimeEnded()?-1:timeEnded>o.getTimeEnded()?1:0;
}

}

প্রাকৃতিক ক্রম উপর ভিত্তি করে সাজানোর জন্য কল সাজানোর পদ্ধতি

Collections.sort(list);

7

Java8 + এ এটি একক লাইনে লেখা যেতে পারে:

collectionObjec.sort(comparator_lamda) অথবা comparator.comparing(CollectionType::getterOfProperty)

কোড:

ListOfActiveAlarmObj.sort((a,b->a.getTimeStarted().compareTo(b.getTimeStarted())))
 

অথবা

ListOfActiveAlarmObj.sort(Comparator.comparing(ActiveAlarm::getTimeStarted))

5
public class ActiveAlarm implements Comparable<ActiveAlarm> {
    public long timeStarted;
    public long timeEnded;
    private String name = "";
    private String description = "";
    private String event;
    private boolean live = false;

    public int compareTo(ActiveAlarm a) {
        if ( this.timeStarted > a.timeStarted )
            return 1;
        else if ( this.timeStarted < a.timeStarted )
            return -1;
        else {
             if ( this.timeEnded > a.timeEnded )
                 return 1;
             else
                 return -1;
        }
 }

এটি আপনাকে একটি মোটামুটি ধারণা দেওয়া উচিত। এটি হয়ে গেলে আপনি Collections.sort()তালিকায় কল করতে পারেন ।


4

জাভা 8 যেহেতু এটি Comparatorএবং এর সংমিশ্রণটি ব্যবহার করে আরও ক্লিনার করা যায়Lambda expressions

উদাহরণ স্বরূপ:

class Student{

    private String name;
    private List<Score> scores;

    // +accessor methods
}

class Score {

    private int grade;
    // +accessor methods
}

    Collections.sort(student.getScores(), Comparator.comparing(Score::getGrade);



1

জাভাতে আপনার স্ট্যাটিক Collections.sortপদ্ধতিটি ব্যবহার করা দরকার । এখানে প্রথমে শুরুর পরে এবং শেষে শেষে সাজানো কোম্পানী রোল অবজেক্টের তালিকার একটি উদাহরণ রয়েছে। আপনি সহজেই আপনার নিজের অবজেক্টের জন্য মানিয়ে নিতে পারেন।

private static void order(List<TextComponent> roles) {

    Collections.sort(roles, new Comparator() {
        @Override
        public int compare(Object o1, Object o2) {
            int x1 = ((CompanyRole) o1).getBegin();
            int x2 = ((CompanyRole) o2).getBegin();

            if (x1 != x2) {
                return x1 - x2;
            } else {
                int y1 = ((CompanyRole) o1).getEnd();
                int y2 = ((CompanyRole) o2).getEnd();
                return y2 - y1;
            }
        }
    });
}

0

আপনি কালেকশনস.সোর্ট () কল করতে পারেন এবং একটি তুলনামূলককে পাস করতে পারেন যা আপনাকে বস্তুর বিভিন্ন বৈশিষ্ট্যের তুলনায় লিখতে হবে।


0

উল্লিখিত হিসাবে আপনি এই অনুসারে বাছাই করতে পারেন:

  • আপনার অবজেক্টকে বাস্তবায়ন করা Comparable
  • অথবা একটি পাস ComparatorথেকেCollections.sort

যদি আপনি উভয়টি করেন Comparableতবে এটি উপেক্ষা করা Comparatorহবে এবং ব্যবহৃত হবে। এটি মান অবজেক্টগুলির নিজস্ব লজিকাল করতে সহায়তা করে যা আপনার মান অবজেক্টের Comparableজন্য সবচেয়ে যুক্তিসঙ্গত বাছাই করা হয়, যখন প্রতিটি ব্যবহারের ক্ষেত্রে তার নিজস্ব প্রয়োগ থাকে has

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.