আমি clone()
একটি বড় প্রকল্পের অভ্যন্তরে বিভিন্ন ক্রিয়াকলাপের জন্য ইউনিট পরীক্ষা লেখার চেষ্টা করছি এবং আমি ভাবছি যে কোথাও কোনও বিদ্যমান শ্রেণি রয়েছে যা একই ধরণের দুটি বস্তু নিতে সক্ষম, গভীর তুলনা করে, এবং যদি তারা বলছে যে 'অভিন্ন বা না?
আমি clone()
একটি বড় প্রকল্পের অভ্যন্তরে বিভিন্ন ক্রিয়াকলাপের জন্য ইউনিট পরীক্ষা লেখার চেষ্টা করছি এবং আমি ভাবছি যে কোথাও কোনও বিদ্যমান শ্রেণি রয়েছে যা একই ধরণের দুটি বস্তু নিতে সক্ষম, গভীর তুলনা করে, এবং যদি তারা বলছে যে 'অভিন্ন বা না?
উত্তর:
ইউনিটিলসের এই কার্যকারিতা রয়েছে:
জাভা ডিফল্ট / নাল মান অগ্রাহ্য করা এবং সংগ্রহের ক্রম উপেক্ষা করার মতো বিভিন্ন বিকল্পের সাথে প্রতিবিম্বের মাধ্যমে সমতা দৃ as়তা
unitils
সঠিকভাবে ত্রুটিযুক্ত কারণ এটি ভেরিয়েবলগুলির সাথে তুলনা করে এমনকি যদি তাদের পর্যবেক্ষণযোগ্য প্রভাব নাও আসে । ভেরিয়েবলের তুলনা করার আরেকটি (অনাকাঙ্ক্ষিত) পরিণতি হ'ল খাঁটি বন্ধ (তাদের নিজস্ব কোনও রাজ্য নেই) সমর্থিত নয়। এছাড়াও, তুলনা করা অবজেক্টগুলি একই রানটাইম টাইপের হওয়া দরকার। আমি আমার আস্তিনগুলি ঘূর্ণিত করেছি এবং এই উদ্বেগগুলির সমাধান করার জন্য গভীর তুলনা সরঞ্জামটির নিজস্ব সংস্করণ তৈরি করেছি ।
আমি এই প্রশ্ন ভালোবাসি! মূলত কারণ এটি কখনও উত্তর দেওয়া হয় না বা খারাপ উত্তর দেওয়া হয় না। এটি এখনও কেউ খুঁজে পায়নি এর মতো। কুমারী অঞ্চল :)
প্রথম বন্ধ, এমনকি ব্যবহার সম্পর্কে চিন্তা করবেন না equals
। চুক্তি equals
, যেমন javadoc সংজ্ঞায়িত, একটি সমানতা সম্পর্ক (আত্মবাচক, প্রতিসম এবং সকর্মক) হয় না একটি সমতা সম্পর্ক। তার জন্য এটি এন্টিসিমমেট্রিকও হতে হবে। এর একমাত্র বাস্তবায়ন equals
(বা কখনও হতে পারে) একটি সত্য সাম্যতা সম্পর্ক হল java.lang.Object
। এমনকি আপনি যদি equals
গ্রাফের সাথে সমস্ত কিছু তুলনা করতে ব্যবহার করেন তবে চুক্তি ভঙ্গ হওয়ার ঝুঁকিটি বেশ বেশি। কার্যকর জোয়ায় জোশ ব্লচ যেমন উল্লেখ করেছেন, সমানদের চুক্তিটি খুব সহজেই ভাঙ্গা যায়:
"সাময়িক চুক্তি সংরক্ষণের সময় কোনও তাত্ক্ষণিক ক্লাস বাড়ানো এবং একটি দিক যুক্ত করার সহজ উপায় নেই"
বুলিয়ান পদ্ধতি আসলে কীভাবে আপনাকে কী করতে পারে তা ছাড়াও? আসল এবং ক্লোনটির মধ্যে সমস্ত পার্থক্যকে প্রকৃতপক্ষে আবদ্ধ করা ভাল লাগবে, আপনি কি ভাবেন না? এছাড়াও, আমি এখানে ধরে নেব যে আপনি গ্রাফের প্রতিটি বস্তুর জন্য তুলনা কোডটি লেখার / বজায় রাখার বিষয়ে বিরক্ত হতে চান না, বরং আপনি এমন কিছু সন্ধান করছেন যা সময়ের সাথে সাথে পরিবর্তনের সাথে সাথে উত্সটি স্কেল করবে।
Soooo, আপনি যা চান তা হ'ল এক ধরণের রাষ্ট্র তুলনা সরঞ্জাম। কীভাবে সেই সরঞ্জামটি প্রয়োগ করা হয় তা সত্যিই আপনার ডোমেন মডেলটির প্রকৃতির এবং আপনার কার্যকারিতা সীমাবদ্ধতার উপর নির্ভরশীল। আমার অভিজ্ঞতায় কোনও জেনেরিক ম্যাজিক বুলেট নেই। এবং এটি প্রচুর পরিমাণে পুনরাবৃত্তির তুলনায় ধীর হবে । তবে ক্লোন ক্রিয়াকলাপের সম্পূর্ণতা পরীক্ষা করার জন্য, এটি কাজটি বেশ ভালভাবে সম্পাদন করবে। আপনার দুটি সেরা বিকল্প হ'ল সিরিয়ালাইজেশন এবং প্রতিবিম্ব।
কিছু সমস্যার মুখোমুখি হবেন:
এক্সস্ট্রিমটি খুব দ্রুত এবং এক্সএমএলউনিতের সাথে মিলিত কোডের কয়েকটি লাইনে কাজ করবে। এক্সএমএলউনিতটি দুর্দান্ত কারণ এটি সমস্ত পার্থক্যের প্রতিবেদন করতে পারে বা এটির প্রথমটি খুঁজে পাওয়া বন্ধ করে দেয়। এবং এর আউটপুটটিতে আলাদা আলাদা নোডের এক্সপাথ অন্তর্ভুক্ত রয়েছে যা দুর্দান্ত is ডিফল্টরূপে এটি অর্ডারড সংগ্রহগুলি মঞ্জুরি দেয় না, তবে এটি করার জন্য এটি কনফিগার করা যেতে পারে। একটি বিশেষ পার্থক্য হ্যান্ডলার ইনজেকশন (বলা হয় একটিDifferenceListener
যাকে ) উপেক্ষা সহ আপনি যেভাবে পার্থক্যগুলি মোকাবেলা করতে চান তা সুনির্দিষ্ট করতে দেয়। তবে, আপনি যত তাড়াতাড়ি সাধারণ কাস্টমাইজেশনের বাইরে কিছু করতে চান, লিখতে অসুবিধা হয় এবং বিশদটি নির্দিষ্ট ডোমেন অবজেক্টের সাথে আবদ্ধ থাকে।
আমার ব্যক্তিগত অগ্রাধিকার হ'ল সমস্ত ঘোষিত ক্ষেত্রগুলিতে চক্রের প্রতিবিম্ব ব্যবহার করা এবং প্রত্যেকটিতে illুকিয়ে দেওয়া, আমার যেতে পার্থক্যের সন্ধান করা। সতর্কতার শব্দ: আপনি যদি স্ট্যাক ওভারফ্লো ব্যতিক্রম পছন্দ না করেন তবে পুনরাবৃত্তি ব্যবহার করবেন না। স্ট্যাকের সাহায্যে জিনিসগুলিকে সুযোগে রাখুন (একটি ব্যবহার করুন aLinkedList
অথবা অন্যকিছু). আমি সাধারণত ক্ষণস্থায়ী এবং স্থিতিশীল ক্ষেত্রগুলিকে অগ্রাহ্য করি এবং আমি ইতিমধ্যে তুলনা করা অবজেক্টের জোড়গুলি এড়িয়ে চলেছি, তাই যদি কেউ স্ব-রেফারেন্সিয়াল কোড লেখার সিদ্ধান্ত নেন তবে আমি অসীম লুপগুলিতে শেষ করি না (তবে আমি সর্বদা আদিম মোড়কের তুলনা করি না কেন যাই হোক না কেন , যেহেতু একই অবজেক্ট রেফগুলি প্রায়শই পুনরায় ব্যবহৃত হয়)। সংগ্রহের ক্রমটিকে অগ্রাহ্য করতে এবং বিশেষ ধরণের বা ক্ষেত্রগুলি উপেক্ষা করতে আপনি সামনের জিনিসগুলি কনফিগার করতে পারেন, তবে আমি টীকাগুলির মাধ্যমে ক্ষেত্রগুলিতে আমার রাজ্যের তুলনা নীতিগুলি সংজ্ঞায়িত করতে চাই। এটি, আইএমএইচও, রানটাইমে ক্লাস সম্পর্কে মেটা ডেটা তৈরি করার জন্য, টীকাগুলির ঠিক কী বোঝানো হয়েছিল। কিছুটা এইরকম:
@StatePolicy(unordered=true, ignore=false, exactTypesOnly=true)
private List<StringyThing> _mylist;
আমি মনে করি এটি আসলেই একটি কঠিন সমস্যা, তবে সম্পূর্ণ সমাধানযোগ্য! এবং একবার আপনার জন্য কাজ করে এমন কিছু হয়ে গেলে, এটি সত্যই, সত্যই, কার্যকর ...
সুতরাং ভালো থাকুন. এবং আপনি যদি এমন কিছু নিয়ে আসেন যা কেবল খাঁটি প্রতিভা, ভাগ করতে ভুলবেন না!
জাভা-ব্যবহারের মধ্যে ডিপক্যুয়ালস এবং ডিপহ্যাশকোড () দেখুন: https://github.com/jdereg/java-util
এই শ্রেণিটি মূল লেখকের অনুরোধ অনুযায়ী ঠিক তাই করে।
public
যা কেবল সংগ্রহ / মানচিত্রের ক্ষেত্রে প্রযোজ্য তার বিপরীতে সমস্ত প্রকারের ক্ষেত্রে কী প্রযোজ্য তা কেবল তুলনা করে ।
এখানে বর্ণিত হিসাবে আপনি ইক্যুয়াল বিল্ডার.রেফলেশনএকুয়ালস () ব্যবহার করে ক্লাসের সমান () সমান পদ্ধতিটি কেবল ওভাররাইড করতে পারেন :
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
ইন AssertJ , আপনি করতে পারেন:
Assertions.assertThat(expectedObject).isEqualToComparingFieldByFieldRecursively(actualObject);
সম্ভবত এটি সমস্ত ক্ষেত্রে কাজ করবে না, তবে এটি আপনার মনে হতে পারে এমন আরও বেশি ক্ষেত্রে কাজ করবে।
এখানে ডকুমেন্টেশন কী বলে:
জোর দিয়ে নিন যে পরীক্ষার অধীনে থাকা অবজেক্টটি সম্পত্তি / ক্ষেত্রের তুলনায় (উত্তরাধিকারসূত্রে অন্তর্ভুক্ত) দ্বারা সম্পত্তি / ক্ষেত্র পুনরাবৃত্ত করার উপর ভিত্তি করে প্রদত্ত বস্তুর সমান। বাস্তবের সমান বাস্তবায়ন যদি আপনার উপযুক্ত না হয় তবে এটি কার্যকর হতে পারে। পুনরাবৃত্ত সম্পত্তি / ক্ষেত্রের তুলনা প্রয়োগ করা হয় না কাস্টম সমান বাস্তবায়নের ক্ষেত্রগুলিতে, অর্থাত্ ওভাররাইড সমান পদ্ধতিটি ক্ষেত্রের তুলনায় ক্ষেত্রের পরিবর্তে ব্যবহৃত হবে।
পুনরাবৃত্তির তুলনা চক্র পরিচালনা করে। ডিফল্টরূপে ভাসমানগুলির সাথে তুলনা করা হয় 1.0E-6 এর নির্ভুলতার সাথে এবং 1.0E-15 এর সাথে ডাবলস।
আপনি প্রতি (নেস্টেড) ক্ষেত্রগুলিতে একটি কাস্টম তুলক নির্দিষ্ট করতে পারেন বা যথাক্রমে কমপোরেটরফরফিল্ডস (তুলনাকারী, স্ট্রিং ...) এবং কমার্পেটর ফোরটাইপ (তুলনকারী, শ্রেণি) ব্যবহার করে টাইপ করতে পারেন।
তুলনা করার জন্য অবজেক্টগুলি বিভিন্ন ধরণের হতে পারে তবে একই বৈশিষ্ট্য / ক্ষেত্র থাকতে হবে। উদাহরণস্বরূপ যদি প্রকৃত অবজেক্টটির একটি নাম স্ট্রিং ফিল্ড থাকে তবে এটি অন্য বস্তুরও একটি থাকার প্রত্যাশা করে। যদি কোনও জিনিসের ক্ষেত্র এবং একই নামের একটি সম্পত্তি থাকে তবে সম্পত্তি মানটি ক্ষেত্রের উপরে ব্যবহার করা হবে।
isEqualToComparingFieldByFieldRecursively
এখন অবচয় করা হয়েছে। assertThat(expectedObject).usingRecursiveComparison().isEqualTo(actualObject);
পরিবর্তে ব্যবহার করুন :)
কেবলমাত্র হাইবারনেট এনভার্স দ্বারা সংশোধিত দুটি সত্তার উদাহরণগুলির তুলনা বাস্তবায়ন করতে হয়েছিল। আমি আমার নিজস্ব লিখতে শুরু করেছি তবে নীচের কাঠামোটি পেয়েছি।
https://github.com/SQiShER/java-object-diff
আপনি একই ধরণের দুটি বস্তুর তুলনা করতে পারেন এবং এটি পরিবর্তন, সংযোজন এবং অপসারণগুলি প্রদর্শন করবে। যদি কোনও পরিবর্তন না হয় তবে বস্তুগুলি সমান (তত্ত্ব অনুসারে)। গ্রাহকদের জন্য টীকাগুলি সরবরাহ করা হয় যা চেক চলাকালীন উপেক্ষা করা উচিত। সাম্যতা যাচাইয়ের চেয়ে ফ্রেমের কাজের অনেক বেশি বিস্তৃত অ্যাপ্লিকেশন রয়েছে, অর্থাত্ আমি একটি পরিবর্তন-লগ তৈরি করতে ব্যবহার করছি।
এর পারফরম্যান্স ঠিক আছে, জেপিএ সত্তাগুলির সাথে তুলনা করার সময়, প্রথমে সত্তা ব্যবস্থাপকের কাছ থেকে এটিকে আলাদা করে রাখার বিষয়ে নিশ্চিত হন।
আমি ইউএসএন স্ট্রিম:
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object o) {
XStream xstream = new XStream();
String oxml = xstream.toXML(o);
String myxml = xstream.toXML(this);
return myxml.equals(oxml);
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
XStream xstream = new XStream();
String myxml = xstream.toXML(this);
return myxml.hashCode();
}
http://www.unitils.org/tutorial-reflectionassert.html
public class User {
private long id;
private String first;
private String last;
public User(long id, String first, String last) {
this.id = id;
this.first = first;
this.last = last;
}
}
User user1 = new User(1, "John", "Doe");
User user2 = new User(1, "John", "Doe");
assertReflectionEquals(user1, user2);
Hamcrest ম্যাচার হয়েছে samePropertyValuesAs । তবে এটি জাভাবিয়ান কনভেনশন (গেটার এবং সেটটার ব্যবহার করে) এর উপর নির্ভর করে। যে বস্তুগুলির সাথে তুলনা করতে হবে তাদের বৈশিষ্ট্যের জন্য গিটার এবং সেটার না থাকলে এটি কার্যকর হবে না।
import static org.hamcrest.beans.SamePropertyValuesAs.samePropertyValuesAs;
import static org.junit.Assert.assertThat;
import org.junit.Test;
public class UserTest {
@Test
public void asfd() {
User user1 = new User(1, "John", "Doe");
User user2 = new User(1, "John", "Doe");
assertThat(user1, samePropertyValuesAs(user2)); // all good
user2 = new User(1, "John", "Do");
assertThat(user1, samePropertyValuesAs(user2)); // will fail
}
}
ব্যবহারকারীর শিম - গিটার এবং সেটটার সহ
public class User {
private long id;
private String first;
private String last;
public User(long id, String first, String last) {
this.id = id;
this.first = first;
this.last = last;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFirst() {
return first;
}
public void setFirst(String first) {
this.first = first;
}
public String getLast() {
return last;
}
public void setLast(String last) {
this.last = last;
}
}
isFoo
কোনও Boolean
সম্পত্তির জন্য পঠন পদ্ধতি ব্যবহার করে না । এটি ঠিক করার জন্য একটি পিআর রয়েছে যা ২০১ 2016 সাল থেকে উন্মুক্ত। github.com/hamcrest/ JavaHamcrest
যদি আপনার অবজেক্টগুলি সিরিয়ালাইজেবল কার্যকর করে তবে আপনি এটি ব্যবহার করতে পারেন:
public static boolean deepCompare(Object o1, Object o2) {
try {
ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
ObjectOutputStream oos1 = new ObjectOutputStream(baos1);
oos1.writeObject(o1);
oos1.close();
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
ObjectOutputStream oos2 = new ObjectOutputStream(baos2);
oos2.writeObject(o2);
oos2.close();
return Arrays.equals(baos1.toByteArray(), baos2.toByteArray());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
আপনার লিঙ্কযুক্ত তালিকার উদাহরণটি পরিচালনা করা এতটা কঠিন নয়। কোডটি দুটি অবজেক্টের গ্রাফকে অতিক্রম করার সাথে সাথে এটি পরিদর্শন করা বস্তুগুলিকে একটি সেট বা মানচিত্রে রাখে। অন্য কোনও বস্তুর রেফারেন্সে প্রবেশের আগে, এই সেটটি ইতিমধ্যে বস্তুটি ট্র্যাভারসড হয়েছে কিনা তা পরীক্ষা করা হয়। যদি তা হয় তবে আর এগিয়ে যাওয়ার দরকার নেই।
আমি উপরের ব্যক্তির সাথে সম্মত যিনি বলেছিলেন যে লিংকডলিস্টটি ব্যবহার করুন (স্ট্যাকের মতো তবে এটিতে সিঙ্ক্রোনাইজড পদ্ধতি ছাড়াই এটি দ্রুত)। স্ট্যাক ব্যবহার করে অবজেক্টের গ্রাফের সন্ধান করা, প্রতিটি ক্ষেত্রের প্রতিবিম্বটি ব্যবহার করার সময়, এটি আদর্শ সমাধান। একবার লিখিত, এই "বাহ্যিক" সমান () এবং "বাহ্যিক" হ্যাশকোড () সমস্ত সমান () এবং হ্যাশকোড () পদ্ধতিগুলির কল করা উচিত। আর কখনও আপনার গ্রাহকের সমান () পদ্ধতির দরকার নেই।
আমি কিছুটা কোড লিখেছি যা গুগল কোডে তালিকাভুক্ত একটি সম্পূর্ণ অবজেক্ট গ্রাফকে অনুসরণ করে। Json-io (http://code.google.com/p/json-io/) দেখুন। এটি JSON- এ একটি জাভা অবজেক্ট গ্রাফকে সিরিয়ালাইজ করে এবং এ থেকে ডিজিট্রাইজড। এটি পাবলিক কনস্ট্রাক্টর, সিরিয়ালাইজেবল বা না সিরিয়ালাইজেবল, ইত্যাদি ছাড়া সমস্ত জাভা অবজেক্ট পরিচালনা করে same বিটিডব্লিউ, জসনরিডার / জসন রাইটার (জসন-আইও) সাধারণত অন্তর্নির্মিত অবজেক্টআইপুটস্ট্রিম / অবজেক্টআউটপুট স্ট্রিমের চেয়ে দ্রুত হয়।
এই JsonReader / JsonWriter তুলনা জন্য ব্যবহার করা যেতে পারে, তবে এটি হ্যাশকোড সাহায্য করবে না। আপনি যদি সর্বজনীন হ্যাশকোড () এবং সমান () চান তবে এটির নিজস্ব কোড দরকার। আমি জেনেরিক গ্রাফ দর্শকের সাথে এটি টানতে সক্ষম হতে পারি। আমরা দেখব.
অন্যান্য বিবেচনা - স্থিতিশীল ক্ষেত্র - এটি সহজ - এগুলি এড়ানো যায় কারণ সমস্ত সমান () উদাহরণগুলির স্থির ক্ষেত্রগুলির জন্য সমান মূল্য থাকবে, কারণ স্থির ক্ষেত্রগুলি সমস্ত দৃষ্টান্ত জুড়ে ভাগ করা হয়।
ক্ষণস্থায়ী ক্ষেত্র হিসাবে - এটি একটি নির্বাচনযোগ্য বিকল্প হবে। কখনও কখনও আপনি স্থানান্তরকারী অন্য সময় না গণনা করতে পারেন। "কখনও কখনও আপনি বাদামের মতো অনুভব করেন, কখনও কখনও করেন না" "
Json-io প্রকল্পে ফিরে দেখুন (আমার অন্যান্য প্রকল্পের জন্য) এবং আপনি বহিরাগত সমান () / হ্যাশকোড () প্রকল্প পাবেন। এটির জন্য এখনও আমার নাম নেই, তবে তা সুস্পষ্ট হবে।
আমার ধারণা আপনি এটি জানেন তবে তত্ত্ব অনুসারে আপনার সর্বদা ওভাররাইড করা উচিত e দুটি বস্তু সত্যই সমান বলে দাবি করার জন্য সমান। এটি বোঝায় যে তারা তাদের সদস্যদের উপরে ওভাররাইড করা .সম্পূর্ণ পদ্ধতিগুলি পরীক্ষা করে।
এই জাতীয় জিনিসটি কেন .সাম্যগুলিকে অবজেক্টে সংজ্ঞায়িত করা হয়।
এটি যদি ধারাবাহিকভাবে করা হয়ে থাকে তবে আপনার কোনও সমস্যা হবে না।
এত গভীর তুলনার জন্য একটি থামার গ্যারান্টি একটি সমস্যা হতে পারে। নিম্নলিখিতগুলি কি করা উচিত? (আপনি যদি এই ধরণের তুলনামূলক প্রয়োগ করেন তবে এটি ভাল ইউনিট পরীক্ষা করবে))
LinkedListNode a = new LinkedListNode();
a.next = a;
LinkedListNode b = new LinkedListNode();
b.next = b;
System.out.println(DeepCompare(a, b));
এখানে আরও একটি:
LinkedListNode c = new LinkedListNode();
LinkedListNode d = new LinkedListNode();
c.next = d;
d.next = c;
System.out.println(DeepCompare(c, d));
Using an answer instead of a comment to get a longer limit and better formatting.
যদি মন্তব্য হয় তবে উত্তর বিভাগটি কেন ব্যবহার করবেন? এজন্য আমি এটি পতাকাঙ্কিত করেছি। না কারণ ?
। এই উত্তরটি ইতিমধ্যে অন্য কেউ ফ্ল্যাগ করেছেন, যিনি মন্তব্যটি পিছনে রাখেন নি। আমি স্রেফ এটি পর্যালোচনা সারিতে পেয়েছি। আমার খারাপ হতে পারে যে, আমি আরও যত্নবান হওয়া উচিত ছিল।
আমি মনে করি রায় হুলা সমাধান দ্বারা অনুপ্রাণিত করা সবচেয়ে সহজ সমাধান হ'ল বস্তুটিকে সিরিয়ালাইজ করা এবং তারপরে কাঁচা ফলাফলকে গভীরভাবে তুলনা করা।
সিরিয়ালাইজেশন বাইট, জসন, এক্সএমএল বা সাধারণ টো স্ট্রিং ইত্যাদি হতে পারে। টুস্ট্রিং সস্তা বলে মনে হচ্ছে। লম্বোক আমাদের জন্য বিনামূল্যে সহজেই কাস্টমাইজেবল টোস্ট্রিং তৈরি করে। নীচে উদাহরণ দেখুন।
@ToString @Getter @Setter
class foo{
boolean foo1;
String foo2;
public boolean deepCompare(Object other) { //for cohesiveness
return other != null && this.toString().equals(other.toString());
}
}
অ্যাপাচি আপনাকে কিছু দেয়, উভয় বস্তুকে স্ট্রিংয়ে রূপান্তর করে স্ট্রিংগুলির তুলনা করে, তবে আপনাকে টু স্ট্রিংকে ওভাররাইড করতে হবে ()
obj1.toString().equals(obj2.toString())
টু স্ট্রিংকে ওভাররাইড করুন ()
যদি সমস্ত ক্ষেত্র আদিম ধরণের হয়:
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
@Override
public String toString() {return
ReflectionToStringBuilder.toString(this);}
আপনার যদি আদিম ক্ষেত্র এবং / অথবা সংগ্রহ এবং / বা মানচিত্র না থাকে:
// Within class
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
@Override
public String toString() {return
ReflectionToStringBuilder.toString(this,new
MultipleRecursiveToStringStyle());}
// New class extended from Apache ToStringStyle
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.util.*;
public class MultipleRecursiveToStringStyle extends ToStringStyle {
private static final int INFINITE_DEPTH = -1;
private int maxDepth;
private int depth;
public MultipleRecursiveToStringStyle() {
this(INFINITE_DEPTH);
}
public MultipleRecursiveToStringStyle(int maxDepth) {
setUseShortClassName(true);
setUseIdentityHashCode(false);
this.maxDepth = maxDepth;
}
@Override
protected void appendDetail(StringBuffer buffer, String fieldName, Object value) {
if (value.getClass().getName().startsWith("java.lang.")
|| (maxDepth != INFINITE_DEPTH && depth >= maxDepth)) {
buffer.append(value);
} else {
depth++;
buffer.append(ReflectionToStringBuilder.toString(value, this));
depth--;
}
}
@Override
protected void appendDetail(StringBuffer buffer, String fieldName,
Collection<?> coll) {
for(Object value: coll){
if (value.getClass().getName().startsWith("java.lang.")
|| (maxDepth != INFINITE_DEPTH && depth >= maxDepth)) {
buffer.append(value);
} else {
depth++;
buffer.append(ReflectionToStringBuilder.toString(value, this));
depth--;
}
}
}
@Override
protected void appendDetail(StringBuffer buffer, String fieldName, Map<?, ?> map) {
for(Map.Entry<?,?> kvEntry: map.entrySet()){
Object value = kvEntry.getKey();
if (value.getClass().getName().startsWith("java.lang.")
|| (maxDepth != INFINITE_DEPTH && depth >= maxDepth)) {
buffer.append(value);
} else {
depth++;
buffer.append(ReflectionToStringBuilder.toString(value, this));
depth--;
}
value = kvEntry.getValue();
if (value.getClass().getName().startsWith("java.lang.")
|| (maxDepth != INFINITE_DEPTH && depth >= maxDepth)) {
buffer.append(value);
} else {
depth++;
buffer.append(ReflectionToStringBuilder.toString(value, this));
depth--;
}
}
}}
জাভা 7, যেহেতু Objects.deepEquals(Object, Object)
।