একটি কাস্টম বাছাই অর্ডার ব্যবহার করে অবজেক্টগুলির একটি অ্যারেলিস্ট বাছাই করা


119

আমি আমার ঠিকানা বইয়ের অ্যাপ্লিকেশনটির জন্য একটি সাজানোর বৈশিষ্ট্যটি প্রয়োগ করতে চাই implement

আমি একটি বাছাই করতে চান ArrayList<Contact> contactArrayContactনাম, বাড়ির নম্বর, মোবাইল নম্বর এবং ঠিকানা: একটি শ্রেণী যা চারটি ক্ষেত্র ধারণ করে। আমি বাছাই করতে চাই name

এটি করার জন্য আমি কীভাবে একটি কাস্টম বাছাই করতে পারি?

উত্তর:


270

অর্ডার করার উদ্দেশ্যে সম্পর্কিত টিউটোরিয়াল এখানে:

যদিও আমি কিছু উদাহরণ দেব, তবে যাইহোক এটি পড়ার পরামর্শ দেব।


একটি বাছাই করার বিভিন্ন উপায় আছে ArrayList। যদি আপনি কোনও প্রাকৃতিক (ডিফল্ট) ক্রম সংজ্ঞায়িত করতে চান তবে আপনাকে Contactবাস্তবায়ন করতে হবে Comparable। ধরে nameনিই যে আপনি ডিফল্ট অনুসারে বাছাই করতে চান , তারপরে (সরলতার জন্য বাদ দেওয়া শূন্যস্থানগুলি):

public class Contact implements Comparable<Contact> {

    private String name;
    private String phone;
    private Address address;

    public int compareTo(Contact other) {
        return name.compareTo(other.name);
    }

    // Add/generate getters/setters and other boilerplate.
}

যাতে আপনি ঠিক করতে পারেন

List<Contact> contacts = new ArrayList<Contact>();
// Fill it.

Collections.sort(contacts);

আপনি যদি কোনও বাহ্যিক নিয়ন্ত্রণযোগ্য অর্ডারিং (যা প্রাকৃতিক ক্রমকে ওভার্রাইড করে) সংজ্ঞায়িত করতে চান , তবে আপনাকে একটি তৈরি করতে হবে Comparator:

List<Contact> contacts = new ArrayList<Contact>();
// Fill it.

// Now sort by address instead of name (default).
Collections.sort(contacts, new Comparator<Contact>() {
    public int compare(Contact one, Contact other) {
        return one.getAddress().compareTo(other.getAddress());
    }
}); 

এমনকি আপনি নিজের Comparatorমধ্যে এটি সংজ্ঞায়িত Contactকরতে পারেন যাতে আপনি প্রতিবার পুনরায় তৈরি করার পরিবর্তে সেগুলি পুনরায় ব্যবহার করতে পারেন:

public class Contact {

    private String name;
    private String phone;
    private Address address;

    // ...

    public static Comparator<Contact> COMPARE_BY_PHONE = new Comparator<Contact>() {
        public int compare(Contact one, Contact other) {
            return one.phone.compareTo(other.phone);
        }
    };

    public static Comparator<Contact> COMPARE_BY_ADDRESS = new Comparator<Contact>() {
        public int compare(Contact one, Contact other) {
            return one.address.compareTo(other.address);
        }
    };

}

যা নিম্নলিখিত হিসাবে ব্যবহার করা যেতে পারে:

List<Contact> contacts = new ArrayList<Contact>();
// Fill it.

// Sort by address.
Collections.sort(contacts, Contact.COMPARE_BY_ADDRESS);

// Sort later by phone.
Collections.sort(contacts, Contact.COMPARE_BY_PHONE);

এবং উপরের অংশটি ক্রিম করার জন্য, আপনি জেনেরিক জাবাবেইনের তুলনামূলক ব্যবহার করতে পারেন :

public class BeanComparator implements Comparator<Object> {

    private String getter;

    public BeanComparator(String field) {
        this.getter = "get" + field.substring(0, 1).toUpperCase() + field.substring(1);
    }

    public int compare(Object o1, Object o2) {
        try {
            if (o1 != null && o2 != null) {
                o1 = o1.getClass().getMethod(getter, new Class[0]).invoke(o1, new Object[0]);
                o2 = o2.getClass().getMethod(getter, new Class[0]).invoke(o2, new Object[0]);
            }
        } catch (Exception e) {
            // If this exception occurs, then it is usually a fault of the developer.
            throw new RuntimeException("Cannot compare " + o1 + " with " + o2 + " on " + getter, e);
        }

        return (o1 == null) ? -1 : ((o2 == null) ? 1 : ((Comparable<Object>) o1).compareTo(o2));
    }

}

যা আপনি নিম্নলিখিত হিসাবে ব্যবহার করতে পারেন:

// Sort on "phone" field of the Contact bean.
Collections.sort(contacts, new BeanComparator("phone"));

(আপনি কোডটিতে দেখতে পাচ্ছেন, সম্ভবত এনপিই এর বাছাইয়ের সময় এড়াতে নাল ক্ষেত্রগুলি ইতিমধ্যে কভার করা হয়েছে)


2
আমি বেশ কয়েকটি
তুলককে

2
আসলে, আমি সবেমাত্র করেছি। নিজেকে বোঝানোর চেষ্টা করার চেয়ে সহজ।
স্টোবর

@ বালুসসি: কোনও প্রোব নেই। আমি ধারণার জন্য কৃতিত্ব নিতে পারি না, এটি আমি String.CASE_INSENSITIVE_ORDERএবং বন্ধুদের কাছ থেকে পেয়েছি তবে আমি এটি পছন্দ করি। ফলাফলের কোডটি পড়া সহজ করে তোলে।
স্টোবর

1
সেই comparator সংজ্ঞা সম্ভবত এছাড়াও হওয়া উচিত staticএবং হয়ত finalখুব ... অথবা যে .. ভালো কিছু
Stobor

হিহহ ... বিয়ানকম্পেটর দুর্দান্ত একটি স্টিকের মতো! :-) ( (o1 == null && o2 == null) ? 0 :
নালগুলির সাথে

28

ইতিমধ্যে যা পোস্ট করা হয়েছিল তা ছাড়াও আপনার জানা উচিত যে জাভা 8 এর পরে আমরা আমাদের কোডটি সংক্ষিপ্ত করে এটি লিখতে পারি:

Collection.sort(yourList, Comparator.comparing(YourClass::getFieldToSortOn));

বা যেহেতু তালিকার এখন sortপদ্ধতি রয়েছে

yourList.sort(Comparator.comparing(YourClass::getFieldToSortOn));

ব্যাখ্যা:

জাভা 8 থেকে, কার্যকরী ইন্টারফেস (কেবলমাত্র একটি বিমূর্ত পদ্ধতিযুক্ত ইন্টারফেসগুলি - তাদের আরও ডিফল্ট বা স্ট্যাটিক পদ্ধতি থাকতে পারে) ব্যবহার করে সহজেই প্রয়োগ করা যেতে পারে:

যেহেতু Comparator<T>কেবল একটি বিমূর্ত পদ্ধতি রয়েছে int compare(T o1, T o2)এটি কার্যকরী ইন্টারফেস।

সুতরাং পরিবর্তে ( @ বালাসক উত্তর থেকে উদাহরণ )

Collections.sort(contacts, new Comparator<Contact>() {
    public int compare(Contact one, Contact other) {
        return one.getAddress().compareTo(other.getAddress());
    }
}); 

আমরা এই কোডটি এটিকে হ্রাস করতে পারি:

Collections.sort(contacts, (Contact one, Contact other) -> {
     return one.getAddress().compareTo(other.getAddress());
});

আমরা এড়িয়ে (বা কোনও) ল্যাম্বডাকে সহজ করে দিতে পারি

  • আর্গুমেন্টের প্রকারগুলি (জাভা তাদের পদ্ধতির স্বাক্ষরের উপর ভিত্তি করে অনুমান করবে)
  • বা {return...}

পরিবর্তে তাই

(Contact one, Contact other) -> {
     return one.getAddress().compareTo(other.getAddress();
}

আমরা লিখতে পারি

(one, other) -> one.getAddress().compareTo(other.getAddress())

এছাড়াও এখন Comparatorস্ট্যাটিক পদ্ধতি রয়েছে comparing(FunctionToComparableValue)বা comparing(FunctionToValue, ValueComparator)যা আমরা সহজেই তুলনাকারী তৈরি করতে ব্যবহার করতে পারি যা অবজেক্টগুলি থেকে কিছু নির্দিষ্ট মানের তুলনা করা উচিত।

অন্য কথায় আমরা উপরের কোডটি আবার লিখতে পারি

Collections.sort(contacts, Comparator.comparing(Contact::getAddress)); 
//assuming that Address implements Comparable (provides default order).

8

এই পৃষ্ঠাটি আপনাকে অ্যারেলিস্টের মতো সংগ্রহগুলি বাছাই করার বিষয়ে আপনার যা জানা দরকার তা বলে দেয়।

মূলত আপনার প্রয়োজন

  • আপনার Contactশ্রেণি Comparableদ্বারা ইন্টারফেস বাস্তবায়ন করতে
    • public int compareTo(Contact anotherContact)এটির মধ্যে একটি পদ্ধতি তৈরি করা।
  • একবার আপনি এটি করার পরে, আপনি কেবল কল করতে পারেন Collections.sort(myContactList);,
    • যেখানে myContactListহয় ArrayList<Contact>(অথবা অন্য কোন সংগ্রহে Contact)।

তুলনামূলক ক্লাস তৈরির সাথে জড়িত আরও একটি উপায় রয়েছে এবং আপনি সে সম্পর্কে লিঙ্কযুক্ত পৃষ্ঠা থেকেও পড়তে পারেন।

উদাহরণ:

public class Contact implements Comparable<Contact> {

    ....

    //return -1 for less than, 0 for equals, and 1 for more than
    public compareTo(Contact anotherContact) {
        int result = 0;
        result = getName().compareTo(anotherContact.getName());
        if (result != 0)
        {
            return result;
        }
        result = getNunmber().compareTo(anotherContact.getNumber());
        if (result != 0)
        {
            return result;
        }
        ...
    }
}

5

বালাসসি এবং বগুইজ ইতিমধ্যে জাভা-র অন্তর্নির্মিত তুলকগুলি কীভাবে ব্যবহার করবেন সে সম্পর্কে খুব সম্পূর্ণ উত্তর দিয়েছে।

আমি কেবল যুক্ত করতে চাই যে গুগল-সংগ্রহে একটি অর্ডারিং ক্লাস রয়েছে যা মান তুলনামূলক তুলনায় আরও "শক্তিশালী"। এটি চেক আউট মূল্য হতে পারে। আপনি দুর্দান্ত জিনিসগুলি যেমন অর্ডিংগুলি মিশ্রণ করা, সেগুলি বিপরীত করা, আপনার সামগ্রীর জন্য কোনও ফাংশনের ফলাফলের উপর নির্ভর করে অর্ডার করা ...

এখানে একটি ব্লগ পোস্ট এখানে এর কিছু সুবিধার উল্লেখ রয়েছে।


নোট করুন যে গুগল-সংগ্রহগুলি এখন পেয়ারা (গুগলের সাধারণ জাভা গ্রন্থাগারসমূহ) এর একটি অঙ্গ, সুতরাং আপনি যদি অর্ডারিং ক্লাসটি ব্যবহার করতে চান তবে আপনি পেয়ারা (বা পেয়ারা সংগ্রহের মডিউল) এর উপর নির্ভর করতে পারেন।
এটিয়েন নেভু

4

আপনার নিজের পরিচিতি ক্লাসগুলিকে তুলনামূলক প্রয়োগ করতে হবে এবং তারপরে compareTo(Contact)পদ্ধতিটি বাস্তবায়ন করতে হবে । এইভাবে, কালেকশনস.সোর্ট আপনার জন্য সেগুলি সাজাতে সক্ষম করবে। আমি যে পৃষ্ঠাটিতে লিঙ্ক করেছি, প্রতি তুলনা করুন 'নির্দিষ্ট করে দেওয়া বস্তুর চেয়ে কম, সমান বা বৃহত্তর হিসাবে একটি negativeণাত্মক পূর্ণসংখ্যা, শূন্য বা ধনাত্মক পূর্ণসংখ্যা প্রদান করে।'

উদাহরণস্বরূপ, আপনি যদি নাম (A থেকে Z) অনুসারে বাছাই করতে চান তবে আপনার শ্রেণিটি এমন দেখাবে:

public class Contact implements Comparable<Contact> {

    private String name;

    // all the other attributes and methods

    public compareTo(Contact other) {
        return this.name.compareTo(other.name);
    }
}

আমার সাথে ভাল কাজ করেছেন, ধন্যবাদ! কেসটি উপেক্ষা করার জন্য আমি তুলনা করুনআইগনোরকেসও ব্যবহার করেছি।
রানী ক্ষীর

3

ল্যাম্বডেজ ব্যবহার করে আপনি নীচের মত আপনার পরিচিতিগুলির একটি সংগ্রহ (উদাহরণস্বরূপ তাদের নামে) বাছাই করতে পারেন

sort(contacts, on(Contact.class).getName());

বা তাদের ঠিকানা দ্বারা:

sort(contacts, on(Contacts.class).getAddress());

ইত্যাদি। আরও সাধারণভাবে, এটি আপনার সংগ্রহগুলিকে বিভিন্ন উপায়ে অ্যাক্সেস এবং পরিচালনা করার জন্য একটি ডিএসএল সরবরাহ করে, যেমন কিছু শর্তের উপর ভিত্তি করে আপনার পরিচিতিগুলিকে ফিল্টারিং বা গোষ্ঠীকরণ, তাদের সম্পত্তির কিছু মান একত্রিত করা ইত্যাদি to


0

কালেকশনস.সোর্ট একটি ভাল সাজানোর বাস্তবায়ন। যদি আপনার সাথে যোগাযোগের তুলনামূলক প্রয়োগযোগ্য না হয়, আপনাকে তুলনাকারী বাস্তবায়নে পাস করতে হবে

নোট:

বাছাই করা অ্যালগরিদম হল একটি পরিবর্তিত মার্জকোর্ট (যার মধ্যে নিম্ন সাবলিস্টে সর্বাধিক উপাদান উচ্চ সাবলিস্টের সর্বনিম্ন উপাদানের চেয়ে কম হলে মার্জটি বাদ দেওয়া হবে)। এই অ্যালগরিদম গ্যারান্টিযুক্ত এন লগ (এন) এর কার্যকারিতা সরবরাহ করে। নির্দিষ্ট তালিকাটি অবশ্যই পরিবর্তনযোগ্য, তবে পুনরায় আকার পরিবর্তন করার দরকার নেই। এই প্রয়োগটি নির্দিষ্ট তালিকাটিকে একটি অ্যারেতে ফেলে দেয়, অ্যারে বাছাই করে এবং অ্যারেতে সম্পর্কিত অবস্থান থেকে প্রতিটি উপাদানকে পুনরায় সেট করে তালিকার উপরে পুনরাবৃত্তি করে। এটি এন 2 লগ (এন) কর্মক্ষমতা এড়িয়ে চলে যা কোনও লিঙ্কযুক্ত তালিকাকে স্থানে সাজানোর চেষ্টা করার ফলে আসে।

সংযুক্তি বাছাই করা সর্বাধিক অনুসন্ধান অ্যালগরিদমের চেয়ে সম্ভবত আপনি করতে পারেন।


0

আমি নিম্নলিখিত পদ্ধতিতে এটি করেছি। সংখ্যা এবং নাম দুটি অ্যারেলিস্ট। আমাকে নামটি বাছাই করতে হবে ar

public void sortval(){

        String tempname="",tempnum="";

         if (name.size()>1) // check if the number of orders is larger than 1
            {
                for (int x=0; x<name.size(); x++) // bubble sort outer loop
                {
                    for (int i=0; i < name.size()-x-1; i++) {
                        if (name.get(i).compareTo(name.get(i+1)) > 0)
                        {

                            tempname = name.get(i);

                            tempnum=number.get(i);


                           name.set(i,name.get(i+1) );
                           name.set(i+1, tempname);

                            number.set(i,number.get(i+1) );
                            number.set(i+1, tempnum);


                        }
                    }
                }
            }



}

আপনি এটি লিখতে আরও বেশি সময় নিতে যাচ্ছেন, কম অনুকূল সাজানোর কার্যকারিতা পাবেন, আরও বাগ লিখুন (এবং আশাকরি আরও পরীক্ষা), এবং কোডটি অন্য ব্যক্তির কাছে স্থানান্তর করা আরও শক্ত হবে। সুতরাং এটি ঠিক নয়। এটি কাজ করতে পারে তবে এটি এটি সঠিক করে না।
এরিক

0

এই পদ্ধতিটি ব্যবহার করুন:

private ArrayList<myClass> sortList(ArrayList<myClass> list) {
    if (list != null && list.size() > 1) {
        Collections.sort(list, new Comparator<myClass>() {
            public int compare(myClass o1, myClass o2) {
                if (o1.getsortnumber() == o2.getsortnumber()) return 0;
                return o1.getsortnumber() < o2.getsortnumber() ? 1 : -1;
            }
        });
    }
    return list;
}

`

এবং ব্যবহার: mySortedlist = sortList(myList); আপনার ক্লাসে তুলনামূলক প্রয়োগ করার দরকার নেই। আপনি যদি বিপরীত অর্ডারটি পরিবর্তন করতে চান 1এবং-1


0

ঠিক আছে, আমি জানি এটির উত্তর অনেক আগেই দেওয়া হয়েছিল ... তবে, এখানে কিছু নতুন তথ্য দেওয়া হয়েছে:

জিজ্ঞাসা করা যোগাযোগের শ্রেণীর কাছে তুলনামূলক বাস্তবায়নের মাধ্যমে ইতিমধ্যে একটি সংজ্ঞায়িত প্রাকৃতিক ক্রম রয়েছে তবে আপনি নামটি দিয়ে বলুন যে আপনি এই আদেশটিকে ওভাররাইড করতে চান। এটি করার আধুনিক উপায় এখানে:

List<Contact> contacts = ...;

contacts.sort(Comparator.comparing(Contact::getName).reversed().thenComparing(Comparator.naturalOrder());

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


-1

আপনি চিৎকার করে অ্যারে.সোর্ট ফাংশনটি ব্যবহার করুন। সমন্বিত ক্লাসগুলির তুলনামূলক বাস্তবায়ন করা উচিত।


আমি অ্যারে কেন বললাম।
monksy

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