বাছাই করতে জাভাতে তুলনামূলক কীভাবে ব্যবহার করবেন


169

তুলনামূলক কীভাবে ব্যবহার করতে হয় তা শিখেছি তবে তুলনাকারীর সাথে আমার অসুবিধা হচ্ছে। আমার কোডে আমার একটি ত্রুটি হচ্ছে:

Exception in thread "main" java.lang.ClassCastException: New.People cannot be cast to java.lang.Comparable
 at java.util.Arrays.mergeSort(Unknown Source)
 at java.util.Arrays.sort(Unknown Source)
 at java.util.Collections.sort(Unknown Source)
 at New.TestPeople.main(TestPeople.java:18)

আমার কোডটি এখানে:

import java.util.Comparator;

public class People implements Comparator {
   private int id;
   private String info;
   private double price;

   public People(int newid, String newinfo, double newprice) {
       setid(newid);
       setinfo(newinfo);
       setprice(newprice);
   }

   public int getid() {
       return id;
   }

   public void setid(int id) {
       this.id = id;
   }

   public String getinfo() {
       return info;
   }

   public void setinfo(String info) {
       this.info = info;
   }

   public double getprice() {
       return price;
   }

   public void setprice(double price) {
       this.price = price;
   }

   public int compare(Object obj1, Object obj2) {
       Integer p1 = ((People) obj1).getid();
       Integer p2 = ((People) obj2).getid();

       if (p1 > p2) {
           return 1;
       } else if (p1 < p2){
           return -1;
       } else {
           return 0;
       }
    }
}
import java.util.ArrayList;
import java.util.Collections;

public class TestPeople {
    public static void main(String[] args) {
        ArrayList peps = new ArrayList();

        peps.add(new People(123, "M", 14.25));
        peps.add(new People(234, "M", 6.21));
        peps.add(new People(362, "F", 9.23));
        peps.add(new People(111, "M", 65.99));
        peps.add(new People(535, "F", 9.23));

        Collections.sort(peps);

        for (int i = 0; i < peps.size(); i++){
            System.out.println(peps.get(i));
        }
    }
}

আমি বিশ্বাস করি যে এটি তুলনা পদ্ধতিতে ingালাইয়ের সাথে কিছু করতে হবে তবে আমি এটির সাথে খেলছিলাম এবং এখনও সমাধানটি খুঁজে পাইনি



1
নতুন কোডে কাঁচা ধরণের ব্যবহার করবেন না স্ট্যাকওভারফ্লো :: প্রশ্নগুলি / 2770321/… ; ব্যবহারের Comparator<People>, Comparable<People>, List<People>, ইত্যাদি
polygenelubricants

আমি তুলনামূলক <লোকজন> পরিবর্তন করেছি তবে আমি যখন অ্যারেলিস্ট <লোকজন> পরিবর্তন করি তখন সংগ্রহগুলি.সর্ট একটি ত্রুটি পেয়ে যায়
ড্যান

1
2 ওভারলোড সম্পর্কে আমার উত্তর পড়ুন sort। যদি আপনাকে ব্যবহার করতে বলা হয় Comparator<People>, তবে 2-যুক্তি ব্যবহার করুন sort, 1-যুক্তি sort(যার প্রয়োজন নেই People implements Comparable<People>) ব্যবহার করুন।
বহুবৃত্তীয় পদার্থ

উত্তর:


212

আপনার উদাহরণ শ্রেণীর সাথে বেশ কয়েকটি বিশ্রী জিনিস রয়েছে:

  • একে পিপল বলা হয় যখন এর একটি priceএবং info(বস্তুর জন্য আরও কিছু, লোক নয়) রয়েছে;
  • শ্রেণীর নামকরণকে কোনও কিছুর বহুবচন হিসাবে নামকরণ করার সময় এটি এটি একাধিক জিনিসের বিমূর্ততা বলে প্রস্তাব করে।

যাইহোক, এখানে কীভাবে ব্যবহার করবেন তার একটি ডেমো এখানে রয়েছে Comparator<T>:

public class ComparatorDemo {

    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
                new Person("Joe", 24),
                new Person("Pete", 18),
                new Person("Chris", 21)
        );
        Collections.sort(people, new LexicographicComparator());
        System.out.println(people);
        Collections.sort(people, new AgeComparator());
        System.out.println(people);
    }
}

class LexicographicComparator implements Comparator<Person> {
    @Override
    public int compare(Person a, Person b) {
        return a.name.compareToIgnoreCase(b.name);
    }
}

class AgeComparator implements Comparator<Person> {
    @Override
    public int compare(Person a, Person b) {
        return a.age < b.age ? -1 : a.age == b.age ? 0 : 1;
    }
}

class Person {

    String name;
    int age;

    Person(String n, int a) {
        name = n;
        age = a;
    }

    @Override
    public String toString() {
        return String.format("{name=%s, age=%d}", name, age);
    }
}

সম্পাদনা

এবং একটি সমতুল্য জাভা 8 ডেমো দেখতে পাবেন:

public class ComparatorDemo {

    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
                new Person("Joe", 24),
                new Person("Pete", 18),
                new Person("Chris", 21)
        );
        Collections.sort(people, (a, b) -> a.name.compareToIgnoreCase(b.name));
        System.out.println(people);
        Collections.sort(people, (a, b) -> a.age < b.age ? -1 : a.age == b.age ? 0 : 1);
        System.out.println(people);
    }
}

8
এজক্যাম্পেটর এবং একই ধরণের সংখ্যার তুলনাগুলি ফিরতে সহজ করা যায়a.age - b.age
এসকো লুন্তটোলা

13
@Esko: তুলনা-বাই-বিয়োগ "কৌতুক" সাধারণ জন্য নষ্ট হয়ে গেছে int stackoverflow.com/questions/2728793/...
polygenelubricants

1
@ এসকো: পলিলেগেনুব্রেক্ট্যান্ট যা উল্লেখ করেছেন তার কারণে আমি বরাবরই (যেমন খুব বড় হয়ে উঠবে না) যদিও আপনার উল্লেখ করা বিয়োগগুলি হবে তা আমি সর্বদা এটির মতো করি।
বার্ট কায়ার্স

3
@ সাইকিরান, আপনি পারেন কিন্তু বাস্তবায়ন করার সময় Comparable, এর বিপরীতে তুলনা করার জন্য আপনাকে একটি একক বৈশিষ্ট্য বেছে নিতে হবে। কোনও ব্যক্তির ক্ষেত্রে, অনেকগুলি গুণাবলীর সাথে তুলনা করা যায় যেগুলি: বয়স, দৈর্ঘ্য, লিঙ্গ, নাম ইত্যাদি that ক্ষেত্রে, এই তুলনাগুলি সম্পাদনকারী কয়েকটি তুলনামূলক সরবরাহ করা সহজ।
বার্ট কায়ার্স

1
@ ফার্সবার্গ না, এটি বাধ্যতামূলক নয়, তবে (অত্যন্ত) পরামর্শ দেওয়া হচ্ছে। দেখুন: স্ট্যাকওভারফ্লো.com
বার্ট কায়ার্স

161

এই মুহুর্তে বাছাই করার জন্য একটি সুপার শর্ট টেম্পলেট:

Collections.sort(people,new Comparator<Person>(){
   @Override
   public int compare(final Person lhs,Person rhs) {
     //TODO return 1 if rhs should be before lhs 
     //     return -1 if lhs should be before rhs
     //     return 0 otherwise (meaning the order stays the same)
     }
 });

যদি এটি মনে রাখা শক্ত হয় তবে কেবল মনে রাখার চেষ্টা করুন যে এটি অনুরূপ (সংখ্যার চিহ্নের শর্তে):

 lhs-rhs 

আপনি যদি আরোহী ক্রম অনুসারে বাছাই করতে চান সে ক্ষেত্রে: ক্ষুদ্রতম থেকে বড় সংখ্যায়।


3
@ 40 প্লট, এগুলি অবস্থানের জন্য, তাদের সাথে কোনও শাসক বা অক্ষের চিত্র দিন।
ইউজিন

@ অ্যান্ড্রয়েড বিকাশকারী, কোন অর্ডারের জন্য কোন মানটি ফিরে আসবে তা মনে রাখার কৌশলটি উল্লেখ করার জন্য ধন্যবাদ। :)
গৌর 9৩

compare()সর্বকালের সেরা ব্যাখ্যা ।
মুহাম্মদ বাবর

এছাড়াও java.util.Comparator আমদানি করুন
বিরাজ সিং

@ ভিরাজসিংহ প্রশ্নটি এই শ্রেণীর সম্পর্কে ছিল, অবশ্যই এটিই আমি যার বিষয়ে কথা বলছি ...
অ্যান্ড্রয়েড বিকাশকারী

39

People implements Comparable<People>পরিবর্তে ব্যবহার করুন; এটি প্রাকৃতিক ক্রমটির জন্য সংজ্ঞা দেয় People

একজন Comparator<People>এছাড়াও ছাড়াও সংজ্ঞায়িত করা যায়, কিন্তু People implements Comparator<People>জিনিসগুলি সঠিক উপায় নয়।

দুটি ওভারলোডের জন্য Collections.sortপৃথক:

  • <T extends Comparable<? super T>> void sort(List<T> list)
    • বাছাই করে Comparableতাদের প্রাকৃতিক ক্রম ব্যবহার বস্তু
  • <T> void sort(List<T> list, Comparator<? super T> c)
    • একটি সামঞ্জস্যপূর্ণ ব্যবহার যাই হোক না কেন সাজান Comparator

আপনি দুটিকে বিভ্রান্ত করছেন একটি সাজানোর চেষ্টা করে Comparator(এটি আবার কেন তা বোঝায় না Person implements Comparator<Person>)। আবার, ব্যবহার করতে Collections.sort, আপনার এইগুলির মধ্যে একটি সত্য হওয়া দরকার:

  • প্রকারটি অবশ্যই হবে Comparable(1-আর্গ ব্যবহার করুন sort)
  • Comparatorপ্রকারের জন্য একটি সরবরাহ করা আবশ্যক (২-আর্গ ব্যবহার করুন sort)

সম্পর্কিত প্রশ্নগুলি


এছাড়াও, নতুন কোডে কাঁচা ধরণের ব্যবহার করবেন না । কাঁচা ধরণগুলি অনিরাপদ এবং এটি কেবল সামঞ্জস্যের জন্য সরবরাহ করা হয়।

এটি এর পরিবর্তে:

ArrayList peps = new ArrayList(); // BAD!!! No generic safety!

আপনার টাইপসেফ জেনেরিক ঘোষণাটি ব্যবহার করা উচিত:

List<People> peps = new ArrayList<People>(); // GOOD!!!

তারপরে আপনি দেখতে পাবেন যে আপনার কোডটিও সংকলন করে না !! এটি একটি ভাল জিনিস হবে, কারণ কোডটির সাথে কিছু ভুল আছে ( Personনা implements Comparable<Person>) তবে আপনি কাঁচা টাইপ ব্যবহার করেছেন বলে সংকলক এটি পরীক্ষা করে নি , এবং পরিবর্তে আপনি ClassCastExceptionরান-টাইমে একটি পেতে পারেন !!!

এটি আপনাকে সর্বদা নতুন কোডে টাইপসেফ জেনেরিক প্রকারগুলি ব্যবহার করতে রাজি করা উচিত। সর্বদা.

আরো দেখুন


তুলনামূলক বনাম তুলনামূলক ব্যাখ্যাটি খুব দরকারী
অ্যাডেল

18

সম্পূর্ণতার জন্য, এখানে একটি সহজ ওয়ান-লাইনার compareপদ্ধতি:

Collections.sort(people, new Comparator<Person>() {
    @Override
    public int compare(Person lhs, Person rhs) {  
        return Integer.signum(lhs.getId() - rhs.getId());  
    }
});

2
ব্যবহারের জন্য প্রশংসা করেছেনsignum
msysmilu

1
@ নাম্বারফোর "lhs.getId () - rhs.getId ()" ব্যবহার করা উচিত নয়, এটিতে পূর্ণসংখ্যার ওভারফ্লো পরিবর্তন হয়।
নিরাজ.নিজ্জু

স্ট্রিংয়ের জন্য "রিটার্ন lhs.getName ()। তুলনা করুন (rhs.getName ());"।
আলী আহমেদ

1
Integer.compare(lhs.getId(), rhs.getId());একটি ভাল পদ্ধতির হয়। @ নিরাজ.নিজ্জু উল্লিখিত বিয়োগ বিয়োগের ফলে ওভারফ্লো হতে পারে।
নরেন্দ্র-চৌধুরী চৌদ্দ

12

জাভা 8 Comparators যে আপনার কাছে লিখনের, আছে কোডের পরিমাণ হ্রাস তৈরীর একটি নতুন উপায় যোগ Comparator.comparing । এছাড়াও চেক আউট Comparator.reversed

এখানে একটি নমুনা

import org.junit.Test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import static org.junit.Assert.assertTrue;

public class ComparatorTest {

    @Test
    public void test() {
        List<Person> peopleList = new ArrayList<>();
        peopleList.add(new Person("A", 1000));
        peopleList.add(new Person("B", 1));
        peopleList.add(new Person("C", 50));
        peopleList.add(new Person("Z", 500));
        //sort by name, ascending
        peopleList.sort(Comparator.comparing(Person::getName));
        assertTrue(peopleList.get(0).getName().equals("A"));
        assertTrue(peopleList.get(peopleList.size() - 1).getName().equals("Z"));
        //sort by name, descending
        peopleList.sort(Comparator.comparing(Person::getName).reversed());
        assertTrue(peopleList.get(0).getName().equals("Z"));
        assertTrue(peopleList.get(peopleList.size() - 1).getName().equals("A"));
        //sort by age, ascending
        peopleList.sort(Comparator.comparing(Person::getAge));
        assertTrue(peopleList.get(0).getAge() == 1);
        assertTrue(peopleList.get(peopleList.size() - 1).getAge() == 1000);
        //sort by age, descending
        peopleList.sort(Comparator.comparing(Person::getAge).reversed());
        assertTrue(peopleList.get(0).getAge() == 1000);
        assertTrue(peopleList.get(peopleList.size() - 1).getAge() == 1);
    }

    class Person {

        String name;
        int age;

        Person(String n, int a) {
            name = n;
            age = a;
        }

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }

        public void setName(String name) {
            this.name = name;
        }

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



}

4

আপনি তুলনামূলক নয়, তুলনামূলক বাস্তবায়ন করতে চান। আপনার তুলনা করার পদ্ধতিটি প্রয়োগ করতে হবে। আপনি যদিও কাছাকাছি। তুলনামূলক একটি "তৃতীয় পক্ষ" তুলনা রুটিন। তুলনীয় হ'ল এই বস্তুকে অন্যের সাথে তুলনা করা যায়।

public int compareTo(Object obj1) {
  People that = (People)obj1;
  Integer p1 = this.getId();
  Integer p2 = that.getid();

  if (p1 > p2 ){
   return 1;
  }
  else if (p1 < p2){
   return -1;
  }
  else
   return 0;
 }

দ্রষ্টব্য, আপনি getId..Adसला ক্ষেত্রে এখানে নালাগুলি পরীক্ষা করতে চাইতে পারেন।


আমি এটি বাড়ির কাজ উল্লেখ করতে ভুলে গিয়েছিলাম, আমাকে বিশেষত তুলনামূলক ব্যবহার করতে বলা হয়েছিল
ড্যান

2

এখানে একটি তুলনাকারীর একটি উদাহরণ যা কোনও তুলনামূলক ফিরিয়ে দেয় এমন কোনও শূন্য আর্গ পদ্ধতির জন্য কাজ করবে। এই জাতীয় কিছু একটি জেডি কে বা লাইব্রেরিতে বিদ্যমান?

import java.lang.reflect.Method;
import java.util.Comparator;

public class NamedMethodComparator implements Comparator<Object> {

    //
    // instance variables
    //

    private String methodName;

    private boolean isAsc;

    //
    // constructor
    //

    public NamedMethodComparator(String methodName, boolean isAsc) {
        this.methodName = methodName;
        this.isAsc = isAsc;
    }

    /**
     * Method to compare two objects using the method named in the constructor.
     */
    @Override
    public int compare(Object obj1, Object obj2) {
        Comparable comp1 = getValue(obj1, methodName);
        Comparable comp2 = getValue(obj2, methodName);
        if (isAsc) {
            return comp1.compareTo(comp2);
        } else {
            return comp2.compareTo(comp1);
        }
    }

    //
    // implementation
    //

    private Comparable getValue(Object obj, String methodName) {
        Method method = getMethod(obj, methodName);
        Comparable comp = getValue(obj, method);
        return comp;
    }

    private Method getMethod(Object obj, String methodName) {
        try {
            Class[] signature = {};
            Method method = obj.getClass().getMethod(methodName, signature);
            return method;
        } catch (Exception exp) {
            throw new RuntimeException(exp);
        }
    }

    private Comparable getValue(Object obj, Method method) {
        Object[] args = {};
        try {
            Object rtn = method.invoke(obj, args);
            Comparable comp = (Comparable) rtn;
            return comp;
        } catch (Exception exp) {
            throw new RuntimeException(exp);
        }
    }

}

এটা সত্যিই দুর্দান্ত!
ঝুরভ কনস্টান্টিন

2

শেষ করার জন্য.

জাভা 8 ব্যবহার করে

people.sort(Comparator.comparingInt(People::getId));

আপনি যদি চান descending order

people.sort(Comparator.comparingInt(People::getId).reversed());

তালিকার মধ্যে দুটি সম্পত্তি একই তুলনায় ব্যবহার করা হয় একই সম্পত্তি মান, যা এই ক্ষেত্রে, হয় কি People::getId?
কোক হাও তেহ

.thenComparing()সংঘর্ষের সময় আপনি একটি ধারা যুক্ত করতে পারেন ।
অঙ্কিত শর্মা

ফলাফল না হলে কী হবে .thenComparing()?
কোক

তারপরে এটি রেকর্ডগুলি যে ক্রমে উপস্থিত ছিল তার উপর নির্ভর করে, geeforforgeeks.org/stability-in-sorting-algorithms
অঙ্কিত শর্মা

আমি কীভাবে জানব যদি ব্যবহৃত বাছাই করা অ্যালগরিদম স্থিতিশীল বা অস্থির হয়?
কোক হাও তেহ

1
public static Comparator<JobSet> JobEndTimeComparator = new Comparator<JobSet>() {
            public int compare(JobSet j1, JobSet j2) {
                int cost1 = j1.cost;
                int cost2 = j2.cost;
                return cost1-cost2;
            }
        };

1

সমাধানটি নিম্নলিখিত উপায়ে অপ্টিমাইজ করা যায়: প্রথমত, ক্ষেত্রগুলির জন্য ক্ষেত্রের ক্ষেত্রটি বেষ্টনকারী শ্রেণি টেস্টপিলি হিসাবে বেসরকারী অভ্যন্তর শ্রেণিকে ব্যবহার করুন যাতে শ্রেণি প্রয়োগের ফলে লোকেরা বহিরাগতের সংস্পর্শে না আসে। এটি একটি এপিআই তৈরির ক্ষেত্রে বোঝা যায় যা লোকেদের সাজানো তালিকা প্রত্যাশা করে দ্বিতীয়ত, লাম্বা এক্সপ্রেশন (জাভা 8) ব্যবহার করে যা কোড হ্রাস করে, তাই উন্নয়নের প্রচেষ্টা

সুতরাং কোড নীচের মত হবে:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class TestPeople {
    public static void main(String[] args) {
        ArrayList<People> peps = new ArrayList<>();// Be specific, to avoid
                                                    // classCast Exception

        TestPeople test = new TestPeople();

        peps.add(test.new People(123, "M", 14.25));
        peps.add(test.new People(234, "M", 6.21));
        peps.add(test.new People(362, "F", 9.23));
        peps.add(test.new People(111, "M", 65.99));
        peps.add(test.new People(535, "F", 9.23));

        /*
         * Collections.sort(peps);
         * 
         * for (int i = 0; i < peps.size(); i++){
         * System.out.println(peps.get(i)); }
         */

        // The above code can be replaced by followin:

        peps.sort((People p1, People p2) -> p1.getid() - p2.getid());

        peps.forEach((p) -> System.out.println(" " + p.toString()));

    }

    private class People {
        private int id;

        @Override
        public String toString() {
            return "People [id=" + id + ", info=" + info + ", price=" + price + "]";
        }

        private String info;
        private double price;

        public People(int newid, String newinfo, double newprice) {
            setid(newid);
            setinfo(newinfo);
            setprice(newprice);
        }

        public int getid() {
            return id;
        }

        public void setid(int id) {
            this.id = id;
        }

        public String getinfo() {
            return info;
        }

        public void setinfo(String info) {
            this.info = info;
        }

        public double getprice() {
            return price;
        }

        public void setprice(double price) {
            this.price = price;
        }
    }
}

0

আপনার ওভারলোডেড সাজ্ট (পিপস, নতুন লোক ()) পদ্ধতিটি ব্যবহার করা উচিত

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Test 
{
    public static void main(String[] args) 
    {
        List<People> peps = new ArrayList<>();

        peps.add(new People(123, "M", 14.25));
        peps.add(new People(234, "M", 6.21));
        peps.add(new People(362, "F", 9.23));
        peps.add(new People(111, "M", 65.99));
        peps.add(new People(535, "F", 9.23));

        Collections.sort(peps, new People().new ComparatorId());

        for (int i = 0; i < peps.size(); i++)
        {
            System.out.println(peps.get(i));
        }
    }
}

class People
{
       private int id;
       private String info;
       private double price;

       public People()
       {

       }

       public People(int newid, String newinfo, double newprice) {
           setid(newid);
           setinfo(newinfo);
           setprice(newprice);
       }

       public int getid() {
           return id;
       }

       public void setid(int id) {
           this.id = id;
       }

       public String getinfo() {
           return info;
       }

       public void setinfo(String info) {
           this.info = info;
       }

       public double getprice() {
           return price;
       }

       public void setprice(double price) {
           this.price = price;
       }

       class ComparatorId implements Comparator<People>
       {

        @Override
        public int compare(People obj1, People obj2) {
               Integer p1 = obj1.getid();
               Integer p2 = obj2.getid();

               if (p1 > p2) {
                   return 1;
               } else if (p1 < p2){
                   return -1;
               } else {
                   return 0;
               }
            }
       }
    }

এটি কাজ করবে তবে এটি একটি খারাপ প্যাটার্ন। কোনও শ্রেণীর নিজস্ব 'তুলক' হওয়া উচিত নয়।
গ্লোরফাইন্ডেল

0

একটি সাধারণ তুলনামূলক সরঞ্জামের জন্য আমার উত্তর এখানে

public class Comparator {
public boolean isComparatorRunning  = false;
public void compareTableColumns(List<String> tableNames) {
    if(!isComparatorRunning) {
        isComparatorRunning = true;
        try {
            for (String schTableName : tableNames) {
                Map<String, String> schemaTableMap = ComparatorUtil.getSchemaTableMap(schTableName); 
                Map<String, ColumnInfo> primaryColMap = ComparatorUtil.getColumnMetadataMap(DbConnectionRepository.getConnectionOne(), schemaTableMap);
                Map<String, ColumnInfo> secondaryColMap = ComparatorUtil.getColumnMetadataMap(DbConnectionRepository.getConnectionTwo(), schemaTableMap);
                ComparatorUtil.publishColumnInfoOutput("Comparing table : "+ schemaTableMap.get(CompConstants.TABLE_NAME));
                compareColumns(primaryColMap, secondaryColMap);
            }
        } catch (Exception e) {
            ComparatorUtil.publishColumnInfoOutput("ERROR"+e.getMessage());
        }
        isComparatorRunning = false;
    }
}

public void compareColumns(Map<String, ColumnInfo> primaryColMap, Map<String, ColumnInfo> secondaryColMap) {
    try {
        boolean isEqual = true;
        for(Map.Entry<String, ColumnInfo> entry : primaryColMap.entrySet()) {
            String columnName = entry.getKey();
            ColumnInfo primaryColInfo = entry.getValue();
            ColumnInfo secondaryColInfo = secondaryColMap.remove(columnName);
            if(secondaryColInfo == null) {
                // column is not present in Secondary Environment
                ComparatorUtil.publishColumnInfoOutput("ALTER", primaryColInfo);
                isEqual = false;
                continue;
            }
            if(!primaryColInfo.equals(secondaryColInfo)) {
                isEqual = false;
                // Column not equal in secondary env
                ComparatorUtil.publishColumnInfoOutput("MODIFY", primaryColInfo);
            }
        }
        if(!secondaryColMap.isEmpty()) {
            isEqual = false;
            for(Map.Entry<String, ColumnInfo> entry : secondaryColMap.entrySet()) {
                // column is not present in Primary Environment
                ComparatorUtil.publishColumnInfoOutput("DROP", entry.getValue());
            }
        }

        if(isEqual) {
            ComparatorUtil.publishColumnInfoOutput("--Exact Match");
        }
    } catch (Exception e) {
        ComparatorUtil.publishColumnInfoOutput("ERROR"+e.getMessage());
    }
}

public void compareTableColumnsValues(String primaryTableName, String primaryColumnNames, String primaryCondition, String primaryKeyColumn, 
        String secTableName, String secColumnNames, String secCondition, String secKeyColumn) {
    if(!isComparatorRunning) {
        isComparatorRunning = true;
        Connection conn1 = DbConnectionRepository.getConnectionOne();
        Connection conn2 = DbConnectionRepository.getConnectionTwo();

        String query1 = buildQuery(primaryTableName, primaryColumnNames, primaryCondition, primaryKeyColumn);
        String query2 = buildQuery(secTableName, secColumnNames, secCondition, secKeyColumn);
        try {
            Map<String,Map<String, Object>> query1Data = executeAndRefactorData(conn1, query1, primaryKeyColumn);
            Map<String,Map<String, Object>> query2Data = executeAndRefactorData(conn2, query2, secKeyColumn);

            for(Map.Entry<String,Map<String, Object>> entry : query1Data.entrySet()) {
                String key = entry.getKey();
                Map<String, Object> value = entry.getValue();
                Map<String, Object> secondaryValue = query2Data.remove(key);
                if(secondaryValue == null) {
                    ComparatorUtil.publishColumnValuesInfoOutput("NO SUCH VALUE AVAILABLE IN SECONDARY DB "+ value.toString());
                    continue;
                }
                compareMap(value, secondaryValue, key);
            }

            if(!query2Data.isEmpty()) {
                ComparatorUtil.publishColumnValuesInfoOutput("Extra Values in Secondary table "+ ((Map)query2Data.values()).values().toString());
            }
        } catch (Exception e) {
            ComparatorUtil.publishColumnValuesInfoOutput("ERROR"+e.getMessage());
        }
        isComparatorRunning = false;
    }
}

private void compareMap(Map<String, Object> primaryValues, Map<String, Object> secondaryValues, String columnIdentification) {
    for(Map.Entry<String, Object> entry : primaryValues.entrySet()) {
        String key = entry.getKey();
        Object value = entry.getValue();
        Object secValue = secondaryValues.get(key);
        if(value!=null && secValue!=null && !String.valueOf(value).equalsIgnoreCase(String.valueOf(secValue))) {
            ComparatorUtil.publishColumnValuesInfoOutput(columnIdentification+" : Secondary Table does not match value ("+ value +") for column ("+ key+")");
        }
        if(value==null && secValue!=null) {
            ComparatorUtil.publishColumnValuesInfoOutput(columnIdentification+" : Values not available in primary table for column "+ key);
        }
        if(value!=null && secValue==null) {
            ComparatorUtil.publishColumnValuesInfoOutput(columnIdentification+" : Values not available in Secondary table for column "+ key);
        }
    }
}

private String buildQuery(String tableName, String column, String condition, String keyCol) {
    if(!"*".equalsIgnoreCase(column)) {
        String[] keyColArr = keyCol.split(",");
        for(String key: keyColArr) {
            if(!column.contains(key.trim())) {
                column+=","+key.trim();
            }
        }
    }
    StringBuilder queryBuilder = new StringBuilder();
    queryBuilder.append("select "+column+" from "+ tableName);
    if(!ComparatorUtil.isNullorEmpty(condition)) {
        queryBuilder.append(" where 1=1 and "+condition);
    }
    return queryBuilder.toString();
}

private Map<String,Map<String, Object>> executeAndRefactorData(Connection connection, String query, String keyColumn) {
    Map<String,Map<String, Object>> result = new HashMap<String, Map<String,Object>>();
    try {
        PreparedStatement preparedStatement = connection.prepareStatement(query);
        ResultSet resultSet = preparedStatement.executeQuery();
        resultSet.setFetchSize(1000);
        if (resultSet != null && !resultSet.isClosed()) {
            while (resultSet.next()) {
                Map<String, Object> columnValueDetails = new HashMap<String, Object>();
                int columnCount = resultSet.getMetaData().getColumnCount();
                for (int i=1; i<=columnCount; i++) {
                    String columnName = String.valueOf(resultSet.getMetaData().getColumnName(i));
                    Object columnValue = resultSet.getObject(columnName);
                    columnValueDetails.put(columnName, columnValue);
                }
                String[] keys = keyColumn.split(",");
                String newKey = "";
                for(int j=0; j<keys.length; j++) {
                    newKey += String.valueOf(columnValueDetails.get(keys[j]));
                }
                result.put(newKey , columnValueDetails);
            }
        }

    } catch (SQLException e) {
        ComparatorUtil.publishColumnValuesInfoOutput("ERROR"+e.getMessage());
    }
    return result;
}

}

একই জন্য ইউটিলিটি সরঞ্জাম

public class ComparatorUtil {

public static Map<String, String> getSchemaTableMap(String tableNameWithSchema) {
    if(isNullorEmpty(tableNameWithSchema)) {
        return null;
    }
    Map<String, String> result = new LinkedHashMap<>();
    int index = tableNameWithSchema.indexOf(".");
    String schemaName = tableNameWithSchema.substring(0, index);
    String tableName = tableNameWithSchema.substring(index+1);
    result.put(CompConstants.SCHEMA_NAME, schemaName);
    result.put(CompConstants.TABLE_NAME, tableName);
    return result;
}

public static Map<String, ColumnInfo> getColumnMetadataMap(Connection conn, Map<String, String> schemaTableMap) {
    try {
        String schemaName = schemaTableMap.get(CompConstants.SCHEMA_NAME);
        String tableName = schemaTableMap.get(CompConstants.TABLE_NAME);
        ResultSet resultSetConnOne = conn.getMetaData().getColumns(null, schemaName, tableName, null);
        Map<String, ColumnInfo> resultSetTwoColInfo = getColumnInfo(schemaName, tableName, resultSetConnOne);
        return resultSetTwoColInfo;
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return null;
}

/* Number Type mapping
 * 12-----VARCHAR
 * 3-----DECIMAL
 * 93-----TIMESTAMP
 * 1111-----OTHER
*/
public static Map<String, ColumnInfo> getColumnInfo(String schemaName, String tableName, ResultSet columns) {
    try {
        Map<String, ColumnInfo> tableColumnInfo = new LinkedHashMap<String, ColumnInfo>();
        while (columns.next()) {
            ColumnInfo columnInfo = new ColumnInfo();
            columnInfo.setSchemaName(schemaName);
            columnInfo.setTableName(tableName);
            columnInfo.setColumnName(columns.getString("COLUMN_NAME"));
            columnInfo.setDatatype(columns.getString("DATA_TYPE"));
            columnInfo.setColumnsize(columns.getString("COLUMN_SIZE"));
            columnInfo.setDecimaldigits(columns.getString("DECIMAL_DIGITS"));
            columnInfo.setIsNullable(columns.getString("IS_NULLABLE"));
            tableColumnInfo.put(columnInfo.getColumnName(), columnInfo);
        }
        return tableColumnInfo;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

public static boolean isNullOrEmpty(Object obj) {
    if (obj == null)
        return true;
    if (String.valueOf(obj).equalsIgnoreCase("NULL")) 
        return true;
    if (obj.toString().trim().length() == 0)
        return true;
    return false;
}



public static boolean isNullorEmpty(String str) {
    if(str == null)
        return true;
    if(str.trim().length() == 0) 
        return true;
    return false;
}

public static void publishColumnInfoOutput(String type, ColumnInfo columnInfo) {
    String str = "ALTER TABLE "+columnInfo.getSchemaName()+"."+columnInfo.getTableName();
    switch(type.toUpperCase()) {
        case "ALTER":
            if("NUMBER".equalsIgnoreCase(columnInfo.getDatatype()) || "DATE".equalsIgnoreCase(columnInfo.getDatatype())) {
                str += " ADD ("+columnInfo.getColumnName()+" "+ columnInfo.getDatatype()+");";
            } else {
                str += " ADD ("+columnInfo.getColumnName()+" "+ columnInfo.getDatatype() +"("+columnInfo.getColumnsize()+"));";
            }
            break;
        case "DROP":
            str += " DROP ("+columnInfo.getColumnName()+");";
            break;
        case "MODIFY":
            if("NUMBER".equalsIgnoreCase(columnInfo.getDatatype()) || "DATE".equalsIgnoreCase(columnInfo.getDatatype())) {
                str += " MODIFY ("+columnInfo.getColumnName()+" "+ columnInfo.getDatatype()+");";
            } else {
                str += " MODIFY ("+columnInfo.getColumnName()+" "+ columnInfo.getDatatype() +"("+columnInfo.getColumnsize()+"));";
            }
            break;
    }
    publishColumnInfoOutput(str);
}

public static Map<Integer, String> allJdbcTypeName = null;

public static Map<Integer, String> getAllJdbcTypeNames() {
    Map<Integer, String> result = new HashMap<Integer, String>();
    if(allJdbcTypeName != null)
        return allJdbcTypeName;
    try {
        for (Field field : java.sql.Types.class.getFields()) {
            result.put((Integer) field.get(null), field.getName());
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return allJdbcTypeName=result;
}

public static String getStringPlaces(String[] attribs) {
    String params = "";
    for(int i=0; i<attribs.length; i++) { params += "?,"; }
    return params.substring(0, params.length()-1);
}

}

কলাম তথ্য ক্লাস

public class ColumnInfo {
private String schemaName;
private String tableName;
private String columnName;
private String datatype;
private String columnsize;
private String decimaldigits;
private String isNullable;

0

দুটি সংশোধন:

  1. আপনি একটি করতে হবে ArrayListএর Peopleবস্তু:

    ArrayList<People> preps = new ArrayList<People>(); 
  2. প্রিপগুলিতে অবজেক্ট যুক্ত করার পরে, ব্যবহার করুন:

    Collections.sort(preps, new CompareId());

এছাড়াও, CompareIdহিসাবে একটি শ্রেণি যুক্ত করুন :

class CompareId implements Comparator {  
    public int compare(Object obj1, Object obj2) {  
        People t1 = (People)obj1;  
        People t2 = (People)obj2;  

        if (t1.marks > t2.marks)  
            return 1;   
        else  
            return -1;
    }  
}

-7

নিজের দ্বারা বাছাই করা অ্যালগরিদম বাস্তবায়নে সময় নষ্ট করবেন না। পরিবর্তে; ব্যবহার

ডেটা বাছাই করতে সংগ্রহ।

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