जावा में "कैनोनिकल फॉर्म" या "कैनोनिकल प्रतिनिधित्व" शब्द का क्या अर्थ है?


90

मैंने अक्सर इस शब्द का इस्तेमाल करते हुए सुना है, लेकिन मैं वास्तव में इसे कभी नहीं समझ पाया हूं।

इसका क्या मतलब है, और कोई भी कुछ उदाहरण दे सकता है / मुझे कुछ लिंक पर इंगित कर सकता है?

संपादित करें: उत्तर के लिए सभी को धन्यवाद। क्या आप मुझे यह भी बता सकते हैं कि प्रभावी जावा में बताए अनुसार विहित निरूपण बराबर () प्रदर्शन में कैसे उपयोगी है?

जवाबों:


56

विकिपीडिया शब्द Canonicalization की ओर इशारा करता है

डेटा को परिवर्तित करने की एक प्रक्रिया जिसमें "मानक" विहित प्रतिनिधित्व में एक से अधिक संभव प्रतिनिधित्व है। यह तुल्यता के लिए विभिन्न अभ्यावेदन की तुलना करने के लिए, अलग-अलग डेटा संरचनाओं की संख्या की गणना करने के लिए, बार-बार गणना को समाप्त करके विभिन्न एल्गोरिदम की दक्षता में सुधार करने के लिए, या एक सार्थक क्रमबद्ध क्रम को लागू करने के लिए संभव बनाने के लिए किया जा सकता है।

यूनिकोड उदाहरण मेरे लिए सबसे अधिक उपयुक्त बनाया:

यूनिकोड मानक में विशेष रूप से UTF-8 में चर-लंबाई एन्कोडिंग, अधिकांश सामान्य वर्णों के लिए एक से अधिक संभव एन्कोडिंग हैं। यह स्ट्रिंग सत्यापन को अधिक जटिल बनाता है, क्योंकि प्रत्येक स्ट्रिंग चरित्र के हर संभव एन्कोडिंग पर विचार किया जाना चाहिए। एक सॉफ्टवेयर कार्यान्वयन जो सभी चरित्र एन्कोडिंग पर विचार नहीं करता है, आवेदन डिजाइन में अवैध माने जाने वाले तारों को स्वीकार करने का जोखिम चलाता है, जो बग या हमलों की अनुमति दे सकता है। समाधान प्रत्येक वर्ण के लिए एक एन्कोडिंग की अनुमति है। कैन्युलाइज़ेशन तब हर स्ट्रिंग वर्ण को उसके एकल अनुमत एन्कोडिंग में अनुवाद करने की प्रक्रिया है। सॉफ़्टवेयर के लिए एक विकल्प यह निर्धारित करने के लिए है कि क्या एक स्ट्रिंग को विहित किया गया है, और फिर इसे अस्वीकार कर दें यदि यह नहीं है। इस मामले में, क्लाइंट / सर्वर के संदर्भ में, कैनोनेज़लाइज़ेशन क्लाइंट की ज़िम्मेदारी होगी।

सारांश में, डेटा के लिए प्रतिनिधित्व का एक मानक रूप। इस रूप से आप तब किसी भी प्रतिनिधित्व को परिवर्तित कर सकते हैं जिसकी आपको आवश्यकता हो सकती है।


64

मेरा मानना ​​है कि विहित के दो संबंधित उपयोग हैं: रूप और उदाहरण।

एक विहित रूप का मतलब है कि एक विशेष प्रकार के संसाधन के मूल्यों को कई तरीकों से वर्णित या प्रस्तुत किया जा सकता है, और उन तरीकों में से एक को इष्ट विहित रूप के रूप में चुना जाता है। (उस फॉर्म को कैनॉनाइज्ड किया जाता है , जैसे कि किताबें जो इसे बाईबल में बनाती हैं, और अन्य फॉर्म नहीं हैं।) एक विहित फॉर्म का एक क्लासिक उदाहरण एक पदानुक्रमित फ़ाइल सिस्टम में पथ है, जहां एक एकल फ़ाइल को कई तरीकों से संदर्भित किया जा सकता है। :

myFile.txt                                   # in current working dir
../conf/myFile.txt                           # relative to the CWD
/apps/tomcat/conf/myFile.txt                 # absolute path using symbolic links
/u1/local/apps/tomcat-5.5.1/conf/myFile.txt  # absolute path with no symlinks

उस फ़ाइल के विहित प्रतिनिधित्व की क्लासिक परिभाषा अंतिम रास्ता होगा। स्थानीय या सापेक्ष पथों के साथ आप बिना संदर्भ जानकारी के संसाधन की विश्व स्तर पर पहचान नहीं कर सकते। निरपेक्ष रास्तों से आप संसाधन की पहचान कर सकते हैं, लेकिन यह नहीं बता सकते कि दो रास्ते एक ही इकाई को संदर्भित करते हैं। दो या अधिक पथों को उनके विहित रूपों में परिवर्तित करने के साथ, आप उपरोक्त सभी कार्य कर सकते हैं, साथ ही यह भी निर्धारित कर सकते हैं कि दो संसाधन समान हैं या नहीं, यदि यह आपके आवेदन के लिए महत्वपूर्ण है ( अलियासिंग समस्या को हल करें )।

ध्यान दें कि संसाधन का विहित रूप स्वयं उस विशेष रूप का एक गुण नहीं है; किसी दिए गए प्रकार के लिए कई संभावित विहित रूप हो सकते हैं जैसे फ़ाइल पथ (कहते हैं, लेक्सिक रूप से सबसे पहले संभव पूर्ण पथ)। एक फॉर्म सिर्फ एक विशेष आवेदन कारण के लिए विहित रूप के रूप में चुना जाता है, या शायद मनमाने ढंग से ताकि सभी एक ही भाषा बोलते हैं।

वस्तुओं को अपने विहित उदाहरणों में रखने के लिए एक ही मूल विचार है, लेकिन एक संसाधन के "सर्वश्रेष्ठ" प्रतिनिधित्व को निर्धारित करने के बजाय, यह मनमाने ढंग से एक ही "सामग्री" के उदाहरणों के वर्ग के एक उदाहरण को विहित संदर्भ के रूप में चुनता है, फिर सभी संदर्भों को रूपांतरित करता है एक विहित उदाहरण का उपयोग करने के लिए बराबर वस्तुओं के लिए।

यह समय और स्थान दोनों के अनुकूलन के लिए एक तकनीक के रूप में इस्तेमाल किया जा सकता है। यदि किसी अनुप्रयोग में समतुल्य वस्तुओं के कई उदाहरण हैं, तो उन सभी को एक विशेष मूल्य के एकल विहित उदाहरण के रूप में हल करने के लिए मजबूर करके, आप सभी को खत्म कर सकते हैं, लेकिन प्रत्येक स्थान और बचत समय में से एक को संभवतः अब आप तुलना कर सकते हैं ऑब्जेक्ट समतुल्यता ( equals()विधि) के विपरीत संदर्भ पहचान (==) के साथ उन मूल्यों ।

विहित उदाहरणों के साथ प्रदर्शन के अनुकूलन का एक उत्कृष्ट उदाहरण समान सामग्री के साथ तार को ढह रहा है। String.intern()एक ही वर्ण अनुक्रम के साथ दो तारों पर कॉल करने के लिए उस पाठ के लिए एक ही कैनोनिकल स्ट्रिंग ऑब्जेक्ट को वापस करने की गारंटी है। यदि आप अपने सभी तार उस कैनोनिकलाइज़र के माध्यम से पास करते हैं, तो आप जानते हैं कि समतुल्य तार वास्तव में समान वस्तु संदर्भ हैं, अर्थात, उपनाम

जावा 5.0+ में एनम प्रकार एक वीर्य के भीतर एक ही विहित उदाहरण का उपयोग करने के लिए एक विशेष एनम मान के सभी उदाहरणों को मजबूर करता है, भले ही मूल्य क्रमबद्ध और deserialized हो। इसीलिए if (day == Days.SUNDAY)अगर Daysआप एक enum टाइप है तो आप java में impunity के साथ उपयोग कर सकते हैं । अपनी कक्षाओं के लिए ऐसा करना निश्चित रूप से संभव है, लेकिन ध्यान रखता है। विवरण और सलाह के लिए जोश बलोच द्वारा प्रभावी जावा पढ़ें ।


31

"कैनोनिकल फॉर्म / प्रतिनिधित्व" को समझने के लिए एक अच्छा उदाहरण "बूलियन" की XML स्कीमा डेटाटाइप परिभाषा को देखना है:

  • बूलियन के "लेक्सिकल प्रतिनिधित्व" में से एक हो सकता है: {true, false, 1, 0}जबकि
  • "कैनोनिकल प्रतिनिधित्व" केवल एक ही हो सकता है {true, false}

यह, संक्षेप में, इसका मतलब है कि

  • "true"और "1"विहित repr के लिए मैप किया गया। "true"तथा
  • "false"और "0"canoncial repr के लिए मैप किया गया।"false"

देख बूलियन के लिए w3 XML स्कीमा डेटाप्रकार परिभाषा


28

शब्द "विहित" केवल "मानक" या "सामान्य" के लिए एक पर्याय है। इसका कोई जावा-विशिष्ट अर्थ नहीं है।


3
कैनोनिकल का मानक या सामान्य आईएमओ की तुलना में अधिक समृद्ध अर्थ है।
स्क्वीड

20

सामान्यता खोए बिना सबसे सरल और सबसे महत्वपूर्ण रूप में कमी


5

इसे याद रखने का एक आसान तरीका यह है कि "कैनोनिकल" का उपयोग धर्मशास्त्रीय हलकों में किया जाता है, विहित सत्य ही वास्तविक सत्य है, इसलिए यदि दो लोगों को यह पता चलता है कि उन्होंने एक ही सत्य पाया है। विहित उदाहरण के साथ भी। अगर आपको लगता है कि आपने उनमें से दो (यानी a.equals(b)) पाए हैं तो आपके पास वास्तव में केवल एक (यानी a == b) है। तो समानता का अर्थ है विहित वस्तु के मामले में पहचान।

अब तुलना के लिए। अब आपके पास उपयोग करने का विकल्प है a==b या a.equals(b) , चूंकि वे विहित उदाहरण के मामले में एक ही उत्तर का उत्पादन करेंगे, लेकिन एक == b संदर्भ की तुलना है (जेवीएम दो संख्याओं की तुलना बहुत तेजी से कर सकता है क्योंकि वे केवल दो 32 बिट पैटर्न की तुलना में हैं करने के लिए a.equals(b)जो एक विधि कॉल और अधिक भूमि के ऊपर शामिल है।


2

एक और अच्छा उदाहरण हो सकता है: आपके पास एक वर्ग है जो कार्टेशियन (x, y, z), गोलाकार (r, थीटा, phi) और बेलनाकार निर्देशांक (r, phi, z) के उपयोग का समर्थन करता है। समानता (समान पद्धति) की स्थापना के प्रयोजनों के लिए, आप शायद सभी अभ्यावेदन को अपने चयन के एक "कैनोनिकल" प्रतिनिधित्व में बदलना चाहते हैं, जैसे गोलाकार निर्देशांक। (या हो सकता है कि आप इसे सामान्य रूप से करना चाहते हैं - अर्थात एक आंतरिक प्रतिनिधित्व का उपयोग करें।) मैं कोई विशेषज्ञ नहीं हूं, लेकिन यह मेरे लिए एक अच्छा ठोस उदाहरण है।


0

विहित प्रतिनिधित्व का मतलब है कि चरित्र को अलग शैली में देखें उदाहरण के लिए यदि मैं एक पत्र लिखता हूं तो इसका मतलब है कि कोई अन्य व्यक्ति पत्र को अलग शैली में लिख सकता है :)

यह ऑप्टीकल चार्ज रिक्रूटमेंट फेल्ड के अनुसार है



0

ओप के विहित रूप के बारे में प्रश्न और यह equalsविधि के प्रदर्शन को कैसे बेहतर बना सकता है, दोनों का उत्तर प्रभावी जावा में दिए गए उदाहरण को विस्तार से दिया जा सकता है।

निम्नलिखित वर्ग पर विचार करें:

public final class CaseInsensitiveString {

  private final String s;

  public CaseInsensitiveString(String s) {
    this.s = Objects.requireNonNull(s);
  }

  @Override 
  public boolean equals(Object o) {
    return o instanceof CaseInsensitiveString && ((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
  }
}

equalsइस उदाहरण में विधि का उपयोग कर लागत जोड़ा गया है Stringकी equalsIgnoreCaseविधि। जैसा कि पाठ में बताया गया है

आप क्षेत्र के एक विहित रूप को स्टोर करना चाहते हैं, ताकि बराबरी विधि एक अधिक महंगी गैर-मानक तुलना की तुलना में विहित रूपों पर एक सस्ती सटीक तुलना कर सके।

यहोशू बलोच क्या मतलब है जब वे कहते हैं करता विहित प्रपत्र ? वैसे, मुझे लगता है कि डोनल का संक्षिप्त जवाब बहुत उपयुक्त है। हम उदाहरण Stringके CaseInsensitiveStringलिए अंतर्निहित क्षेत्र को एक मानक तरीके से संग्रहीत कर सकते हैं , शायद अपरकेस रूप String। अब, आप इस विहित रूप को CaseInsensitiveString, इसके अपरकेस संस्करण को संदर्भित कर सकते हैं , और अपने equalsऔर hashcodeतरीकों में सस्ते मूल्यांकन कर सकते हैं ।


0

RDBMS में ग्राफिकल डेटा, ग्राफ डेटा;
RDBMS में डेटा के "सामान्यीकरण" या "सामान्य रूप" के रूप में सोचें। एक ही डेटा विभिन्न तालिकाओं में मौजूद है, एक विशिष्ट पहचानकर्ता के साथ प्रस्तुत किया गया है और इसे विभिन्न तालिकाओं में मैप किया गया है।
या
ग्राफ़ डेटाबेस में एक डेटा का एक रूप सोचो जो कई त्रिगुणों में प्रतिनिधित्व करता है।

इसका प्रमुख लाभ डीएमएल (डेटा हेरफेर) को और अधिक कुशल बनाना है क्योंकि आप कई के बजाय केवल एक मान (अपडेट / अपडेट) कर सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.