एक जावा चर खुद से अलग कैसे हो सकता है?


106

मैं सोच रहा हूं कि क्या यह सवाल जावा में हल किया जा सकता है (मैं भाषा में नया हूं)। यह कोड है:

class Condition {
    // you can change in the main
    public static void main(String[] args) { 
        int x = 0;
        if (x == x) {
            System.out.println("Ok");
        } else {
            System.out.println("Not ok");
        }
    }
}

मुझे अपनी प्रयोगशाला में निम्नलिखित प्रश्न प्राप्त हुए: आप x == xस्थिति को संशोधित किए बिना पहले मामले को कैसे छोड़ सकते हैं (अर्थात स्थिति को असत्य बनाएं )?


12
मेरा मानना ​​है कि अधिक प्रतिबंध होना चाहिए, अन्यथा यह बहुत खुला है।
फेटीज लिटिल स्टूडेंट

52
क्या यह System.out.println("Gotcha!");टिप्पणी के बजाय सरल है ? :)
stuXnet 12

7
अच्छा है, तो एक डबल है डबल। डबल्यूएएनएन सबसे छोटा जवाब और मेरी "हैक सिर्फ एक धोखा है;)
क्रिश्चियन कुटेबैक

47
यह प्यारा जावा सामान्य ज्ञान है, लेकिन मुझे उम्मीद है कि कोई भी इसे एक साक्षात्कार प्रश्न बनाने पर विचार नहीं करेगा। रोजगार के लिए उम्मीदवारों पर विचार करने वाले लोगों को यह पता लगाने के लिए सबसे अच्छा होना चाहिए कि उम्मीदवार प्रोग्रामिंग को समझता है, न कि वह कितना सामान्य ज्ञान है। मैंने जावा में प्रोग्रामिंग के 17 वर्षों में मुश्किल से फ्लोटिंग पॉइंट संख्याओं का उपयोग किया है, बहुत कम NaN निर्माण, MUCH यह जानते हुए भी कि यह == ऑपरेटर के साथ कैसे व्यवहार करता है ...
arcy

8
@ user1158692 मेरे विचार से, मैं व्यक्तिगत रूप से किसी भी कार्यक्रम से नफरत करता हूं, जहां बुनियादी ऑपरेटरों को ओवरराइड किया गया है और मुझे खुशी है कि मुझे जावा में प्राप्त किसी भी कोड के साथ गड़बड़ नहीं हुई है (मैंने देखा है * वेक्टर क्रॉस उत्पाद और डॉट उत्पाद के रूप में ओवरराइड किया गया है क्योंकि दोनों वेक्टर गुणन के प्रकार हैं; infuriating! जबकि जावा में एक को बुलाया जाता है .cross()और दूसरा है .dot()और कोई भ्रम नहीं है। यह भी तथ्य यह है कि "ओवरराइड == ऑपरेटर और हमेशा झूठे होते हैं" प्रो जावा नहीं हो सकता
रिचर्ड डिंगल

जवाबों:


172

उपयोग करने के लिए एक सरल तरीका है Float.NaN:

float x = Float.NaN;  // <--

if (x == x) {
    System.out.println("Ok");
} else {
    System.out.println("Not ok");
}
ठीक नहीं है

आप उसी के साथ कर सकते हैं Double.NaN


से JLS §15.21.1। संख्यात्मक समानता ऑपरेटर ==और!= :

IEEE 754 मानक के नियमों के अनुसार फ्लोटिंग-पॉइंट समानता परीक्षण किया जाता है:

  • यदि कोई ऑपरेंड NaN है, तो परिणाम है ==, falseलेकिन परिणाम !=है true

    वास्तव में, परीक्षण x!=xहै trueअगर और केवल अगर मूल्य xNaN है।

...


157
int x = 0;
if (x == x) {
    System.out.println("Not ok");
} else {
    System.out.println("Ok");
}

63
हे, यह पूरी तरह से पूछे गए सवाल का जवाब देता है।
डेव न्यूटन

5
@AswinMurugesh राइट, लेकिन अगर हम पूरी तरह से प्रश्न का उत्तर दे रहे हैं जैसा कि यह उत्तर करता है, तो हम elseपूरी तरह से हटा सकते हैं। यह तकनीकी रूप से प्रश्न की शर्तों का उल्लंघन नहीं करेगा।
अर्शजी

67
यह ध्यान में रखते हुए मेरा दूसरा सबसे बड़ा जवाब है कि मुझे यकीन नहीं है कि यह निष्कर्ष निकालना कि मैं बहुत मजाकिया या भद्दा प्रोग्रामर हूं।
जीरो वेनवेल

5
@JeroenVannevel आवश्यकताओं को देखते हुए, मुझे लगता है कि यह सबसे KISS / YAGNI / उचित जवाब है;)
Izkata

12
@jddsantaella: जाहिर है यह बाद में संपादित किया गया था। मूल प्रश्न ने कहा "मैं 'ठीक नहीं' कैसे प्रिंट कर सकता हूं"।
जीरो वेनवेल

147

द्वारा जावा भाषा के विनिर्देशों NaN के बराबर नहीं है NaN

इसलिए कोई भी रेखा जो इसके xबराबर होने NaNका कारण बनती है, जैसे कि

double x=Math.sqrt(-1);

जावा भाषा विनिर्देशों से:

फ्लोटिंग-पॉइंट ऑपरेटर कोई अपवाद नहीं पैदा करते हैं (.11)। एक ऑपरेशन जो ओवरफ्लो पर हस्ताक्षर करता है, एक अनन्तता का उत्पादन करता है, एक ऐसा ऑपरेशन जो कमज़ोर हो जाता है, एक मूल्य मान या एक हस्ताक्षरित शून्य पैदा करता है, और एक ऑपरेशन जिसमें कोई गणितीय निश्चित परिणाम नहीं होता है NaN उत्पन्न करता है। एक संचालक के रूप में NaN के साथ सभी संख्यात्मक संचालन परिणामस्वरूप NaN का उत्पादन करते हैं। जैसा कि पहले ही वर्णित किया गया है, NaN अनियंत्रित है , इसलिए एक या दो NaN को शामिल करने वाला एक संख्यात्मक तुलना ऑपरेशन गलत और किसी भी तरह से होता है! = NaN रिटर्न को शामिल करते हुए तुलना सही होती है, जिसमें x! = X जब x NaN होता है।


@ s @s going एक उचित बिंदु, मैं "कोडिंग कन्वेंशन" को खोजने के लिए इतना व्यस्त था कि मैं वास्तव में सवाल का जवाब देना भूल गया
रिचर्ड टिंगल

यह केवल तभी मान्य होता है जब किसी को ऑब्जेक्ट या डबल के रूप में घोषित किया जाता है।
क्रिश्चियन कुटेबैक

1
@ChristianKuetbach सच, इसके विपरीत किसी भी जानकारी के अभाव में मैंने टिप्पणी की है कि लाइन आउट कुछ भी हो सकती है
रिचर्ड टिंगल

2
यहां तक ​​कि मेरे ठगे गए जवाब सही हैं और नियमों को पूरा करते हैं। मैंने केवल इफ-स्टेटमेंट से पहले एडिट किया और केवल "गोचा! छपा है। मुझे यकीन है, कि यह उत्तर इस पहेली के निर्माता के दिमाग में जवाब नहीं है। लेकिन पहेली अच्छी तरह से परिभाषित नहीं है (अधिकांश सॉफ्टवेयरप्रोजेक्ट्स के रूप में)। )।
क्रिश्चियन कुएटबैच

73

सुनिश्चित नहीं है कि यह एक विकल्प है, लेकिन xस्थानीय चर से एक क्षेत्र में बदलने से दूसरे धागे को ifबयान में बाईं और दाईं ओर के बीच के मूल्य को बदलने की अनुमति मिलेगी ।

यहाँ लघु डेमो है:

class Test {

    static int x = 0;

    public static void main(String[] args) throws Exception {

        Thread t = new Thread(new Change());
        t.setDaemon(true);
        t.start();

        while (true) {
            if (x == x) {
                System.out.println("Ok");
            } else {
                System.out.println("Not ok");
                break;
            }
        }
    }
}

class Change implements Runnable {
    public void run() {
        while (true)
            Test.x++;
    }
}

आउटपुट:

⋮
Ok
Ok
Ok
Ok
Ok
Ok
Ok
Ok
Not ok

8
प्रयास के लिए Haha +1, लेकिन आदमी ... मेरे जावा लैब में किसी के पास कोई ऐसा तरीका नहीं है जो इस तरह से आया हो (प्रशिक्षक शामिल)।
विलियम गॉल

28
@WilliamGaul वास्तव में? मैं हमेशा यद्यपि कि यह मूल उदाहरणों में से एक है जिसमें मल्टीथ्रेडिंग के साथ संभावित समस्याएं दिखाई देती हैं और क्यों लोग जो सोचते हैं कि यह विषय आसान है, कभी भी किसी भी चीज़ के प्रभारी नहीं होना चाहिए :)
साइहेमो

4
मैंने इस मुद्दे के बारे में तब तक नहीं सोचा था जब तक मैं आपका जवाब नहीं पढ़ता। इसे मेरे मानसिक टूलकिट में जोड़ने के लिए धन्यवाद :)
Behe

56

बदली हुई रेखा पढ़ सकती थी।

double x = Double.NaN;

इससे गोत्र छप जाएगा।

जावा भाषा विनिर्देश (JLS) कहता है:

फ्लोटिंग-पॉइंट ऑपरेटर कोई अपवाद नहीं पैदा करते हैं (.11)। एक ऑपरेशन जो ओवरफ्लो पर हस्ताक्षर करता है, एक अनन्तता का उत्पादन करता है, एक ऐसा ऑपरेशन जो अंडरफ्लोज़ एक मूल्य मान या हस्ताक्षरित शून्य का उत्पादन करता है, और एक ऑपरेशन जिसमें कोई गणितीय निश्चित परिणाम नहीं है NaN का उत्पादन करता है। एक संचालक के रूप में NaN के साथ सभी संख्यात्मक संचालन परिणामस्वरूप NaN का उत्पादन करते हैं। जैसा कि पहले ही वर्णित किया गया है, NaN अनियंत्रित है, इसलिए एक या दो NaN को शामिल करने वाला एक संख्यात्मक तुलना ऑपरेशन गलत और किसी भी तरह से रिटर्न करता है! = NaN रिटर्न को शामिल करते हुए तुलना सही है, जिसमें x! = X जब x NaN है।


या एक संकलित त्रुटि में नेतृत्व, अगर एक स्ट्रिंग = "नहीं" के रूप में घोषित किया जाता है; इसलिए मैंने
क्रिश्चियन कुटेबैक

उपरोक्त कोड प्रकारों के बारे में कोई जानकारी नहीं देता है, इसलिए मैंने यह धारणा बना ली है कि यह पहले से परिभाषित नहीं है।
मेक्स डेस

मुझे लगता है कि आपका उत्तर वह उत्तर है, जो पहेली निर्माता के दिमाग में था। लेकिन नियम स्पष्ट नहीं थे। केवल दो नियम दिए गए थे: 1. केवल टिप्पणी के साथ लाइन में सम्मिलित करें और 2. केवल एक "
गोत्चा

पहेली लेखक हमेशा {}
मेक्स डिक

30

मैं इससे प्राप्त करने में कामयाब रहा Gotcha!:

volatile Object a = new Object();

class Flipper implements Runnable {
  Object b = new Object();

  public void run() {
    while (true)  {
      Object olda = a;
      a = b;
      a = olda;
    }
  }

}

public void test() {
  new Thread(new Flipper()).start();

  boolean gotcha = false;
  while (!gotcha) {
    // I've added everything above this - I would therefore say still legal.
    if (a == a) {
      System.out.println("Not yet...");
    } else {
      System.out.println("Gotcha!");
      // Uncomment this line when testing or you'll never terminate.
      //gotcha = true;
    }
  }
}

1
यह केवल टिप्पणी के रूप में सवाल पूछने के लिए अधिक बदलता है।
मेक्स डेस

मैंने ऐसा कुछ करने की कोशिश की है, लेकिन मुझे लगता है कि यह गारंटी है कि यह हमेशा एक ही परिणाम देगा, है ना?
आंद्रे दाउराव

4
@Mex - यह वास्तव में करता है, लेकिन यह मूल का एक और महत्वपूर्ण बिंदु को प्रदर्शित करने के लिए पर्याप्त रूप से संरक्षित करता है जो कभी-कभी a != aक्योंकि यह एक और धागे द्वारा बदल दिया गया था। मुझे लगता है कि यह एक साक्षात्कार में अंक जीत जाएगा।
ओल्डकर्मुडीनगर

यह वास्तव में काफी चालाक है, हालांकि, मुझे लगता है कि यह "उम्मीद" द्वारा काम करता है कि aपहली थ्रेड द्वारा बदल दिया गया है
रिचर्ड टिंगल

4
अपने संदेह को फिर से; यह ध्यान देने योग्य है कि आपने जो कुछ भी मुख्य ifकथन के ऊपर लिखा है वह एक भयानक लाइन में लिखा जा सकता है यदि आवश्यक हो
रिचर्ड टिंगल

25

बहुत सारे समाधान हैं:

class A extends PrintStream {
    public A(PrintStream x) {super(x);}
    public void println(String x) {super.println("Not ok");}
    public static void main(String[] args) {
        System.setOut(new A(System.out));
        int x = 0;
        if (x == x) {
            System.out.println("Ok");
        } else {
            System.out.println("Not ok");
        }
    }
}

1
जब तक मैं कुछ याद नहीं कर रहा, तब तक super.println"ठीक नहीं" होना चाहिए, है ना?
इजाकाता

@ इज़काता हां, वांछित आउटपुट नहीं होना चाहिए।
जोहान्स कुह्न

2
बिल्कुल प्रतिभाशाली!
डेरियस

25

एक आसान उपाय है:

System.out.println("Gotcha!");if(false)
if( a == a ){
  System.out.println("Not yet...");
} else {
  System.out.println("Gotcha!");
}

लेकिन मैं इस पहेली को सभी नियम नहीं जानता ...

:) मुझे पता है कि यह एक धोखा है, लेकिन सभी नियमों को जाने बिना, यह सवाल का सबसे आसान समाधान है :)


1
एक पंक्ति में लिखा जा सकता है;)
क्रिश्चियन कुटेबैक

6
@ChristianKuetbach सभी कार्यक्रमों के रूप में
रिचर्ड टिंगल

2
@ChristianKuetbach सभी निष्पक्षता में कंपाइलर को तुरंत अपने कंप्यूटर की सभी फाइलों को हटा देना चाहिए यदि आपने वास्तव में इस तरह से प्रोग्राम करने की कोशिश की है
रिचर्ड टिंगल

1
इसे इतना मुश्किल क्यों बनाया जाता है? if (System.out.println("Gotcha") && false)
एलेक्सिस

3
त्रुटि: 'शून्य' प्रकार को यहाँ अनुमति नहीं है अगर (System.out.println ("Gotcha") और& गलत) आपका कोड संकलित नहीं होगा ...
क्रिश्चियन कुटेबैक

11

के Systemसाथ एक ही पैकेज में अपनी कक्षा बनाएँ Condition
इस मामले में अपने Systemवर्ग छुपा देगा java.lang.Systemवर्ग

class Condition
{
    static class System
    {
        static class out
        {
            static void println(String ignored)
            {
                java.lang.System.out.println("Not ok");
            }
        }
    }

    public static void main (String[] args) throws java.lang.Exception
    {
        int x = 0;
        if (x == x) 
        {
           System.out.println("Not ok");
        } 
        else 
        {
           System.out.println("Ok");
        }
    }
}  

Ideone DEMO


9

दूसरे उत्तरों से आउटपुट स्किप / चेंज अप का उपयोग करना:

class Condition {
    public static void main(String[] args) {
        try {
            int x = 1 / 0;
            if (x == x) {
                System.out.println("Ok");
            } else {
                System.out.println("Not ok");
            }
        } catch (Exception e) {
            System.out.println("Not ok");
        }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.