मैं मैं सवाल का अंदाजा हो लगता है और जब से मैं Pattern
रों तुलना करने के लिए तरीके की खोज की मैं यहाँ अंत (दो साल बहुत देर हो चुकी शायद, ठीक है, खेद ...)।
मैं परीक्षण लिख रहा हूँ और मुझे पता है कि अगर मेरा एक विधि की उम्मीद पैटर्न देता है की जरूरत है। जबकि toString()
या pattern()
के माध्यम से पाठ समान हो सकता है, झंडे अलग-अलग हो सकते हैं और परिणाम का उपयोग करते समय परिणाम अप्रत्याशित होगा।
कुछ समय पहले मैं toString()
की अपने ही सामान्य कार्यान्वयन लिखा था। यह private
वाले सभी फ़ील्ड एकत्र करता है और एक स्ट्रिंग बनाता है जिसका उपयोग लॉगिंग के लिए और स्पष्ट रूप से परीक्षण के लिए किया जा सकता है। यह दिखाता है कि दो बराबर पैटर्न संकलित करते समय root
और matchRoot
फ़ील्ड अलग थे। यह मानते हुए कि वे दोनों समानता के लिए प्रासंगिक नहीं हैं और चूंकि flag
फ़ील्ड है, तो मेरा समाधान बिल्कुल सही नहीं है, तो सही है।
/**
* Don't call this method from a <code>toString()</code> method with
* <code>useExistingToString</code> set to <code>true</code>!!!
*/
public static String toString(Object object, boolean useExistingToString, String... ignoreFieldNames) {
if (object == null) {
return null;
}
Class<? extends Object> clazz = object.getClass();
if (useExistingToString) {
try {
// avoid the default implementation Object.toString()
Method methodToString = clazz.getMethod("toString");
if (!methodToString.getDeclaringClass().isAssignableFrom(Object.class)) {
return object.toString();
}
} catch (Exception e) {
}
}
List<String> ignoreFieldNameList = Arrays.asList(ignoreFieldNames);
Map<String, Object> fields = new HashMap<String, Object>();
while (clazz != null) {
for (Field field : clazz.getDeclaredFields()) {
String fieldName = field.getName();
if (ignoreFieldNameList.contains(fieldName) || fields.containsKey(fieldName)) {
continue;
}
boolean accessible = field.isAccessible();
if (!accessible) {
field.setAccessible(true);
}
try {
Object fieldValue = field.get(object);
if (fieldValue instanceof String) {
fieldValue = stringifyValue(fieldValue);
}
fields.put(fieldName, fieldValue);
} catch (Exception e) {
fields.put(fieldName, "-inaccessible- " + e.getMessage());
}
if (!accessible) {
field.setAccessible(false);
}
}
// travel upwards in the class hierarchy
clazz = clazz.getSuperclass();
}
return object.getClass().getName() + ": " + fields;
}
public static String stringifyValue(Object value) {
if (value == null) {
return "null";
}
return "'" + value.toString() + "'";
}
और परीक्षण हरा है:
String toString1 = Utility.toString(Pattern.compile("test", Pattern.CASE_INSENSITIVE), false, "root", "matchRoot");
String toString2 = Utility.toString(Pattern.compile("test", Pattern.CASE_INSENSITIVE), false, "root", "matchRoot");
assertEquals(toString1, toString2);
अगर आप तुलना 'pattern' आप झंडे को याद करेंगे:
यहाँ एल्गोरिथ्म के एक जावा कार्यान्वयन है। –
@ मार्कस मलकुस्च - हां, यह एक अन्य कारण है कि 'पैटर्न()' का उपयोग करके 'पैटर्न' ऑब्जेक्ट की तुलना क्यों समस्याग्रस्त हो सकती है। –
पैटर्न ऑब्जेक्ट्स को स्वचालित रूप से कैश नहीं किया गया है। सबूत के रूप में, एपीआई दस्तावेज़ चेतावनी देते हैं कि 'पैटर्न.मैट्स()' और 'स्ट्रिंग # मैचों()' पैटर्न ऑब्जेक्ट का पुन: उपयोग करने की अनुमति नहीं देते हैं, और इसलिए लूप में दोहराए गए कॉल के लिए उपयोग नहीं किया जाना चाहिए। (स्कैनर क्लास * करता है * यह सभी पैटर्न का उपयोग करता है, लेकिन यह आंतरिक रूप से संभालता है।) –