তারিখ অনুসারে অ্যারেলিস্টে অবজেক্টগুলি সাজান?


149

আমি যে উদাহরণটি পাই তা প্রতিটি বর্ণানুক্রমিকভাবে করা সম্পর্কে, যখন আমার তারিখ অনুসারে আমার উপাদানগুলি সাজানো দরকার।

আমার অ্যারেলিস্টে এমন একটি অবজেক্ট রয়েছে যার উপর একটি ডেটামেম্বার একটি ডেটটাইম অবজেক্ট। ডেটটাইমে আমি ফাংশনগুলি কল করতে পারি:

lt() // less-than
lteq() // less-than-or-equal-to

সুতরাং তুলনা করতে আমি যেমন কিছু করতে পারি:

if(myList.get(i).lt(myList.get(j))){
    // ...
}

ইফ ব্লকের ভিতরে আমি কী করব?


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

ধন্যবাদ, আমি সেগুলি একবার দেখে নেব, বাছাইয়ের বিষয়ে কিছুই জানি না

: বেশ কিছু দরকারী জাভা 1.8 সমাধান এই থ্রেড খুঁজে পাওয়া যাবে না stackoverflow.com/questions/36361156/...
lradacher

উত্তর:


417

আপনি আপনার বস্তুর তুলনাযোগ্য করতে পারেন:

public static class MyObject implements Comparable<MyObject> {

  private Date dateTime;

  public Date getDateTime() {
    return dateTime;
  }

  public void setDateTime(Date datetime) {
    this.dateTime = datetime;
  }

  @Override
  public int compareTo(MyObject o) {
    return getDateTime().compareTo(o.getDateTime());
  }
}

এবং তারপরে আপনি এটিকে কল করে বাছাই করুন:

Collections.sort(myList);

তবে কখনও কখনও আপনি নিজের মডেলটি পরিবর্তন করতে চান না, যেমন আপনি যখন বিভিন্ন ধরণের বৈশিষ্ট্য বাছাই করতে চান। সেক্ষেত্রে আপনি ফ্লাইতে তুলনামূলক তৈরি করতে পারেন:

Collections.sort(myList, new Comparator<MyObject>() {
  public int compare(MyObject o1, MyObject o2) {
      return o1.getDateTime().compareTo(o2.getDateTime());
  }
});

তবে উপরেরগুলি কেবল তখনই কাজ করে যদি আপনি নিশ্চিত হন যে তুলনা করার সময় ডেটটাইমটি বাতিল নয়। নালপয়েন্টারএক্সেক্সশনগুলি এড়াতে নালকে পরিচালনা করাও বুদ্ধিমানের:

public static class MyObject implements Comparable<MyObject> {

  private Date dateTime;

  public Date getDateTime() {
    return dateTime;
  }

  public void setDateTime(Date datetime) {
    this.dateTime = datetime;
  }

  @Override
  public int compareTo(MyObject o) {
    if (getDateTime() == null || o.getDateTime() == null)
      return 0;
    return getDateTime().compareTo(o.getDateTime());
  }
}

বা দ্বিতীয় উদাহরণে:

Collections.sort(myList, new Comparator<MyObject>() {
  public int compare(MyObject o1, MyObject o2) {
      if (o1.getDateTime() == null || o2.getDateTime() == null)
        return 0;
      return o1.getDateTime().compareTo(o2.getDateTime());
  }
});

1
ভাল উত্তর. নাল চেক না করে আপনার সংস্করণগুলি কেন অন্তর্ভুক্ত করা দরকার? সুবিধা কী? সঠিক উপায় যদি দ্বিতীয় হয় আপনি কেবল এটি অন্তর্ভুক্ত করতে পারেন এবং গুরুত্বপূর্ণ তথ্যটিকে আরও আকর্ষণীয় করে তুলতে পারেন।
amotzg

17
দুটি কারণ - সরলতা এবং ব্যর্থ দ্রুত। আপনি কোডটি যতটা সম্ভব সহজ হতে চান এবং যদি আপনি নিশ্চিত হন যে আপনার সম্পত্তিটি নালার না হয় তবে আপনি সম্ভবত চান যে আপনার কোডটি যত তাড়াতাড়ি সম্ভব বাতিল হয়ে যায় যদি তার পরিবর্তে অবৈধ তথ্য পাস করে এবং জায়গা থেকে আরও বিচ্ছিন্ন হয়ে যায় যেখানে অবৈধ তথ্য প্রবর্তিত হয়েছিল।
ডোমচি

3
যদি o1 বা o2 নাল হয় তবে 0 ফিরে আসুন; // এই লাইনটি 0 টির ফলে ত্রুটি দেখা দিতে পারে যা বোঝায় যে তারা সমান।
tanyehzheng

@ টানিয়েহেজেং, এটি সঠিক, এটি বিভ্রান্তিকর, তবে মনে রাখবেন যে .compareTo () এর মধ্যে পার্থক্য রয়েছে যা বাছাইকরণ এবং .equals () এর জন্য ব্যবহৃত হয়। এটি কীভাবে আপনার নালগুলি বাছাইয়ের সময় পরিচালনা করা যায় তার উপর নির্ভর করে।
ডোমচি

1
আপনার প্রতিটি তারিখের নাল পৃথকভাবে পরীক্ষা করা উচিত এবং পছন্দসই অনুসারে বাছাই করা উচিত (ক্রমের শুরুতে বা শেষে নাল সাজানো)। অর্থাৎ, যদি একটি তারিখ শূন্য হয় এবং একটি তারিখ শূন্য না হয় তবে 1 বা -1 প্রদান করুন। এটি না করে, নালগুলি বাছাই করা হয় না এবং যেখানেই বাছাইয়ের আগে তালিকায় ছিল সেগুলি সেখানে থাকে।
13:55 এ

64

জাভা 8 সাল থেকে তালিকা ইন্টারফেসটি বাছাই পদ্ধতি সরবরাহ করে। ল্যাম্বডা এক্সপ্রেশনটির সাথে একত্রিত হওয়া সবচেয়ে সহজ সমাধান হবে

// sort DateTime typed list
list.sort((d1,d2) -> d1.compareTo(d2));
// or an object which has an DateTime attribute
list.sort((o1,o2) -> o1.getDateTime().compareTo(o2.getDateTime()));
// or like mentioned by Tunaki
list.sort(Comparator.comparing(o -> o.getDateTime()));

বিপরীতে বাছাই

জাভা 8 বিপরীত বাছাইয়ের জন্য কয়েকটি কার্যকর পদ্ধতি সহ আসে।

//requested by lily
list.sort(Comparator.comparing(o -> o.getDateTime()).reversed());

8
আরও ভাল হবেlist.sort(Comparator.comparing(o -> o.getDateTime()));
টুনাকি

21
এটি সম্পর্কে:list.sort(Comparator.comparing(MyObject::getDateTime)
হোয়াইটব্রো

@ টুনাকি কীভাবে বিপরীত বাছাই করবেন?
লিলি

18

আপনি কালেকশন.সোর্ট পদ্ধতিটি ব্যবহার করতে পারেন। এটি একটি স্থির পদ্ধতি। আপনি এটি তালিকা এবং একটি তুলক পাস। এটি তালিকার উপরে একটি পরিবর্তিত মার্জসর্ট অ্যালগরিদম ব্যবহার করে। এই কারণেই আপনাকে জোড়া তুলনা করতে অবশ্যই এটি তুলনামূলক পাস করতে হবে।

Collections.sort(myList, new Comparator<MyObject> {
   public int compare(MyObject o1, MyObject o2) {
      DateTime a = o1.getDateTime();
      DateTime b = o2.getDateTime();
      if (a.lt(b)) 
        return -1;
      else if (a.lteq(b)) // it's equals
         return 0;
      else
         return 1;
   }
});

মনে রাখবেন যে মাইলিস্ট যদি তুলনামূলক ধরণের হয় (একটি যা তুলনামূলক ইন্টারফেস প্রয়োগ করে) (যেমন তারিখ, পূর্ণসংখ্যা বা স্ট্রিং) আপনি তুলনামূলক বাদ দিতে পারেন এবং প্রাকৃতিক ক্রম ব্যবহার করা হবে।


1
এবং এটি কি মাইলিস্টটি ফিরে আসে বা এটির কিছু হয়ে যায়?

এটি মাইলিস্টটি সংশোধন করে। সুতরাং এটি শেষ হওয়ার পরে এটি বাছাই করা হয়েছে
হেলিওস



8

প্রদত্ত MyObjectএকটি আছে যা DateTimeএকটি সঙ্গে সদস্য getDateTime()পদ্ধতি, আপনি একটি বাছাই করতে পারেন ArrayListযে রয়েছে MyObjectদ্বারা উপাদান DateTimeভালো বস্তু:

Collections.sort(myList, new Comparator<MyObject>() {
    public int compare(MyObject o1, MyObject o2) {
        return o1.getDateTime().lt(o2.getDateTime()) ? -1 : 1;
    }
});

আমি যদি বর্তমান সিস্টেমের সময়ের ভিত্তিতে অর্ডার করতে চাই তবে কী হবে।
ব্যবহারকারী 3

5

আমি এইভাবে সমাধান করেছি:

Collections.sort(MyList, (o1, o2) -> o1.getLastModified().compareTo(o2.getLastModified()));

আশা করি এটি আপনাকে সাহায্য করবে।


কিভাবে তারিখ দ্বারা এটি বিপরীত?
বোকচন্দর

2

জাভা 1.8 প্রবর্তনের সাথে সাথে স্ট্রিমগুলি এই ধরণের সমস্যা সমাধানে খুব দরকারী:

Comparator <DateTime> myComparator = (arg1, arg2) 
                -> {
                    if(arg1.lt(arg2)) 
                       return -1;
                    else if (arg1.lteq(arg2))
                       return 0;
                    else
                       return 1;
                   };

ArrayList<DateTime> sortedList = myList
                   .stream()
                   .sorted(myComparator)
                   .collect(Collectors.toCollection(ArrayList::new));

1

এখানে সমস্ত উত্তর আমি একটি সাধারণ সমস্যার (কমপক্ষে অভিজ্ঞ জাভা বিকাশকারী, যা আমি নই) এর জন্য অ-নেসেসেসিও জটিল বলে মনে করেছি। আমার অনুরূপ সমস্যা হয়েছিল এবং এটির (এবং অন্যান্য) সমাধানগুলি অনুসরণ করেছিলাম, এবং যদিও তারা একটি পয়েন্টার সরবরাহ করেছিল, তবে একটি প্রাথমিকের জন্য আমি উপরে বর্ণিত হিসাবে পেয়েছি। আমার সমাধান, আপনার তারিখের অবজেক্টটিতে কোথায় রয়েছে তার উপর নির্ভর করে, এক্ষেত্রে তারিখটি অবজেক্টের প্রথম উপাদান [] যেখানে ডেটাভেক্টর আপনার অবজেক্টস যুক্ত অ্যারেলিস্ট হয়।

Collections.sort(dataVector, new Comparator<Object[]>() {
    public int compare(Object[] o1, Object[] o2) {
        return ((Date)o1[0]).compareTo(((Date)o2[0]));
    }
});

6
আপনার উত্তরটি এখানে অন্যান্য উত্তরের তুলনায় কীভাবে কম জটিল বা বেশি সঠিক? আমার মতে, উদাহরণস্বরূপ হোয়াইটফ্যাং 32 এর উত্তরটি খুব অনুরূপ এবং আরও সংক্ষিপ্ত।
amotzg

কিছুক্ষণের জন্য দূরে চলে গেলেন, তাই প্রতিক্রিয়াটি দেখতে পেলেন না, তবে তারপরে আবার কখনও ভালো না হয়ে দেরি করলেন। আমি মনে করি হোয়াইটফ্যাংয়ের উত্তরের সংক্ষিপ্ততাটি ছিল আমার (তত্কালীন) অনভিজ্ঞ জাভা বিকাশকারী চোখের প্রতিপত্তি! আমার প্রতিক্রিয়াতে টাইপকাস্টিংয়ের অন্তর্ভুক্তি ছিল ক্লিঞ্জার (আমার মনে তখন অন্তত)। আমার উত্তরটি অন্যের চেয়ে সঠিক ছিল বলে আপনি যখন দাবিটি উত্থাপন করেছেন তখন কী বাকী রয়েছে? বাষ্প ছেড়ে দিচ্ছি আমি মনে করি .. সব ক্ষমা হয়ে গেছে!
নেপুজ

O.getDateTime () টাইপিংয়ের বিষয়ে ছিল না, এটি DateTimeঅপরের কোনও বস্তুর ভিতরে থাকা কোনও সামগ্রীর ওপির বর্ণনা সম্পর্কে । যদি এটি কেবলমাত্র Dateবা DateTimeবস্তুগুলি Comparableছিল তবে সেখানে প্রথমে কোনও প্রয়োজন নেই Comparator
amotzg

আপনার উত্তরটি কম সঠিক বা অন্যথায় কম ভাল বলার অর্থ নয়। এটিকে আরও ভালভাবে বুঝতে সাহায্য করার জন্য আমি কেবলমাত্র তথ্য খুঁজছিলাম। অন্যথায় বলে মনে হলে আমি দুঃখিত।
amotzg

0

এটি একটি পুরানো প্রতিক্রিয়া হতে পারে কিন্তু আমি একটি comparator যে সাজাতে হবে তৈরি করতে এই পোস্ট থেকে কিছু উদাহরণ ব্যবহার ArrayListএর HashMap<String, String>তালিকায় এক বস্তু দ্বারা, টাইমস্ট্যাম্প হচ্ছে যে।

আমার এই জিনিসগুলি রয়েছে:

ArrayList<Map<String, String>> alList = new ArrayList<Map<String, String>>();

মানচিত্রের অবজেক্টগুলি নিম্নরূপ:

Map<String, Object> map = new HashMap<>();
        // of course this is the actual formatted date below in the timestamp
        map.put("timestamp", "MM/dd/yyyy HH:mm:ss"); 
        map.put("item1", "my text goes here");
        map.put("item2", "my text goes here");

এই ম্যাপিংটি হ'ল আমি alList.add(map)লুপের মধ্যে আমার সমস্ত বস্তুগুলি অ্যারের তালিকায় লোড করতে ব্যবহার করি ।

এখন, আমি আমার নিজস্ব তুলনামূলক তৈরি করেছি:

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

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

 public class DateSorter implements Comparator {
     public int compare(Object firstObjToCompare, Object secondObjToCompare) {
    String firstDateString = ((HashMap<String, String>) firstObjToCompare).get("timestamp");
    String secondDateString = ((HashMap<String, String>) secondObjToCompare).get("timestamp");

    if (secondDateString == null || firstDateString == null) {
        return 0;
    }

    // Convert to Dates
    DateTimeFormatter dtf = DateTimeFormat.forPattern("MM/dd/yyyy HH:mm:ss");
    DateTime firstDate = dtf.parseDateTime(firstDateString);
    DateTime secondDate = dtf.parseDateTime(secondDateString);

    if (firstDate.isAfter(secondDate)) return -1;
    else if (firstDate.isBefore(secondDate)) return 1;
    else return 0;
    }
}

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

Collections.sort(alList, new DateSorter());

এটি কাউকে সাহায্য করতে পারে, এজন্যই আমি এটি পোস্ট করেছি। তুলনা () ফাংশনের মধ্যে রিটার্নের বিবৃতি বিবেচনা করুন। এখানে 3 ধরণের ফলাফল রয়েছে। তারা সমান হলে 0 প্রত্যাবর্তন করছে> প্রত্যাবর্তন> 0 প্রথম তারিখ দ্বিতীয় তারিখের আগে হলে এবং ফিরে আসবে <0 প্রথম তারিখ দ্বিতীয় তারিখের পরে হলে। আপনি যদি চান যে আপনার তালিকার বিপরীত ঘটে, তবে কেবল সেই দুটি রিটার্নের বিবৃতি স্যুইচ করুন! সরল =]


আমি এই সম্পর্কে একটি মন্তব্য যোগ করতে চেয়েছিলেন। অ্যারে তালিকা পরিচালনা করার সময় অবশ্যই "নালপয়েন্টারএক্সেপশনস" রয়েছে (রিটার্ন 0 স্টেটমেন্ট দেওয়া আছে)। সুতরাং প্রতিটি কেস আলাদা হবে তাই আপনাকে এগুলি পরিচালনা করতে হবে। উদাহরণস্বরূপ 0 টি অবজেক্টের সাথে একটি তালিকা একটি নালপয়েন্টার এক্সসেপশন বা 1 টি অবজেক্ট সহ একটি তালিকা তৈরি করবে!
ব্র্যান্ডন

0

যুক্তিতে অ্যারেলিস্টটি পাস করুন।

    private static void order(ArrayList<Object> list) {

    Collections.sort(list, new Comparator() {

        public int compare(Object o2, Object o1) {

            String x1 =  o1.Date;
            String x2 =  o2.Date;

                return  x1.compareTo(x2);

        }
    });
}

0

তারিখগুলি সাজানোর জন্য বা না করার জন্য নীচের পদ্ধতির ব্যবহার করুন

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy");

boolean  decendingOrder = true;
    for(int index=0;index<date.size() - 1; index++) {
        if(simpleDateFormat.parse(date.get(index)).getTime() < simpleDateFormat.parse(date.get(index+1)).getTime()) {
            decendingOrder = false;
            break;
        }
    }
    if(decendingOrder) {
        System.out.println("Date are in Decending Order");
    }else {
        System.out.println("Date not in Decending Order");
    }       
}   

1
এটি প্রশ্নের উত্তর বলে মনে হচ্ছে না। এবং দয়া করে অল্পবয়সিদের দীর্ঘকালীন এবং কুখ্যাত সমস্যাযুক্ত SimpleDateFormatক্লাসটি ব্যবহার করতে শিখবেন না । কমপক্ষে প্রথম বিকল্প হিসাবে না। এবং কোনও সংরক্ষণ ছাড়া না। java.timeআধুনিক জাভা তারিখ এবং সময় এপিআই এবং এর মধ্যে আজ আমরা আরও অনেক ভাল DateTimeFormatter
ওলে ভিভি

0

তারিখ শ্রেণি ইতিমধ্যে তুলনামূলক ইন্টারফেস প্রয়োগ করে। ধরে নিচ্ছি আপনার ক্লাসটি নীচে রয়েছে:

public class A {

    private Date dateTime;

    public Date getDateTime() {
        return dateTime;
    }

    .... other variables

}

এবং ধরা যাক যে আপনার কাছে A অবজেক্টগুলির একটি তালিকা রয়েছে List<A> aList, আপনি এটি জাভা 8 এর স্ট্রিম এপিআই (নীচে স্নিপেট) দিয়ে সহজেই সাজতে পারেন:

import java.util.Comparator;
import java.util.stream.Collectors;

...

aList = aList.stream()
        .sorted(Comparator.comparing(A::getDateTime))
        .collect(Collectors.toList())

-1

ভবিষ্যতের দর্শকদের, আমি মনে করি এটিই সহজ সমাধান, যদি আপনার মডেলটিতে একটি স্ট্রিং টাইপ তারিখ থাকে ("2020-01-01 10:00:00" উদাহরণস্বরূপ), তবে কেবল নীচে নেমে যাওয়ার তারিখ অনুসারে ডেটা সাজানোর জন্য নিম্নলিখিত লাইনটি লিখুন সবচেয়ে প্রাচীনতম:

Collections.sort(messages, (o1, o2) -> o2.getMessageDate().compareTo(o1.getMessageDate()));
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.