में खाली अवलोकन करने योग्य उचित रूप से संभालना मेरे पास एक ऐसी स्थिति है जहां मैं डेटाबेस से परिणामों का एक अवलोकन कर रहा हूं। मैं फिर उन्हें फ़िल्टर की श्रृंखला लागू कर रहा हूं। मेरे पास एक ग्राहक है जो परिणाम लॉग कर रहा है। यह मामला हो सकता है कि फिल्टर के बावजूद कोई भी तत्व अपना रास्ता नहीं बना सकता है। मेरा व्यवसाय तर्क बताता है कि यह कोई त्रुटि नहीं है। हालांकि, जब ऐसा होता है तो मेरा ऑनर होता है और इसमें निम्न अपवाद होता है: java.util.NoSuchElementException: Sequence contains no elements
RxJava
क्या इस तरह के अपवाद का पता लगाने और इसे अनदेखा करने के लिए स्वीकार्य अभ्यास है? या क्या इसे संभालने का एक बेहतर तरीका है?
संस्करण 1.0.0 है।
यहां एक साधारण परीक्षण मामला है जो मैं देख रहा हूं जो खुलासा करता है। यह नक्शा तक पहुंचने और कम करने से पहले सभी घटनाओं को फ़िल्टर करने से संबंधित प्रतीत होता है।
java.util.NoSuchElementException: Sequence contains no elements
at rx.internal.operators.OperatorSingle$1.onCompleted(OperatorSingle.java:82)
at rx.internal.operators.NotificationLite.accept(NotificationLite.java:140)
at rx.internal.operators.TakeLastQueueProducer.emit(TakeLastQueueProducer.java:73)
at rx.internal.operators.TakeLastQueueProducer.startEmitting(TakeLastQueueProducer.java:45)
at rx.internal.operators.OperatorTakeLast$1.onCompleted(OperatorTakeLast.java:59)
at rx.internal.operators.OperatorScan$2.onCompleted(OperatorScan.java:121)
at rx.internal.operators.OperatorMap$1.onCompleted(OperatorMap.java:43)
at rx.internal.operators.OperatorFilter$1.onCompleted(OperatorFilter.java:42)
at rx.internal.operators.OnSubscribeFromIterable$IterableProducer.request(OnSubscribeFromIterable.java:79)
at rx.internal.operators.OperatorScan$2$1.request(OperatorScan.java:147)
at rx.Subscriber.setProducer(Subscriber.java:139)
at rx.internal.operators.OperatorScan$2.setProducer(OperatorScan.java:139)
at rx.Subscriber.setProducer(Subscriber.java:133)
at rx.Subscriber.setProducer(Subscriber.java:133)
at rx.internal.operators.OnSubscribeFromIterable.call(OnSubscribeFromIterable.java:47)
at rx.internal.operators.OnSubscribeFromIterable.call(OnSubscribeFromIterable.java:33)
at rx.Observable$1.call(Observable.java:144)
at rx.Observable$1.call(Observable.java:136)
at rx.Observable$1.call(Observable.java:144)
at rx.Observable$1.call(Observable.java:136)
at rx.Observable$1.call(Observable.java:144)
at rx.Observable$1.call(Observable.java:136)
at rx.Observable$1.call(Observable.java:144)
at rx.Observable$1.call(Observable.java:136)
at rx.Observable$1.call(Observable.java:144)
at rx.Observable$1.call(Observable.java:136)
at rx.Observable.subscribe(Observable.java:7284)
नीचे @davem से जवाब के आधार पर, मैं एक नया परीक्षण का मामला बनाया:
@Test
public void test()
{
Integer values[] = new Integer[]{1, 2, 3, 4, 5};
Observable.from(values).filter(new Func1<Integer, Boolean>()
{
@Override
public Boolean call(Integer integer)
{
if (integer < 0)
return true;
else
return false;
}
}).map(new Func1<Integer, String>()
{
@Override
public String call(Integer integer)
{
return String.valueOf(integer);
}
}).reduce(new Func2<String, String, String>()
{
@Override
public String call(String s, String s2)
{
return s + "," + s2;
}
})
.subscribe(new Action1<String>()
{
@Override
public void call(String s)
{
System.out.println(s);
}
});
}
क्योंकि मैं एक सुरक्षित ग्राहक का उपयोग कर रहा है, यह शुरू में एक OnErrorNotImplementedException जो निम्न अपवाद लपेटता फेंकता
@Test
public void testFromBlockingAndSingle()
{
Integer values[] = new Integer[]{-2, -1, 0, 1, 2, 3, 4, 5};
List<String> results = Observable.from(values).filter(new Func1<Integer, Boolean>()
{
@Override
public Boolean call(Integer integer)
{
if (integer < 0)
return true;
else
return false;
}
}).map(new Func1<Integer, String>()
{
@Override
public String call(Integer integer)
{
return String.valueOf(integer);
}
}).reduce(new Func2<String, String, String>()
{
@Override
public String call(String s, String s2)
{
return s + "," + s2;
}
}).toList().toBlocking().single();
System.out.println("Test: " + results + " Size: " + results.size());
}
और इस परीक्षण के परिणाम निम्न व्यवहार में:
जब इनपुट है:
Integer values[] = new Integer[]{-2, -1, 0, 1, 2, 3, 4, 5};
तो परिणाम (उम्मीद के रूप में) कर रहे हैं:
Test: [-2,-1] Size: 1
और जब इनपुट है:
Integer values[] = new Integer[]{0, 1, 2, 3, 4, 5};
फिर परिणाम निम्न स्टैक ट्रेस है :
java.util.NoSuchElementException: Sequence contains no elements
at rx.internal.operators.OperatorSingle$1.onCompleted(OperatorSingle.java:82)
at rx.internal.operators.NotificationLite.accept(NotificationLite.java:140)
at rx.internal.operators.TakeLastQueueProducer.emit(TakeLastQueueProducer.java:73)
at rx.internal.operators.TakeLastQueueProducer.startEmitting(TakeLastQueueProducer.java:45)
at rx.internal.operators.OperatorTakeLast$1.onCompleted(OperatorTakeLast.java:59)
at rx.internal.operators.OperatorScan$2.onCompleted(OperatorScan.java:121)
at rx.internal.operators.OperatorMap$1.onCompleted(OperatorMap.java:43)
at rx.internal.operators.OperatorFilter$1.onCompleted(OperatorFilter.java:42)
at rx.internal.operators.OnSubscribeFromIterable$IterableProducer.request(OnSubscribeFromIterable.java:79)
at rx.internal.operators.OperatorScan$2$1.request(OperatorScan.java:147)
at rx.Subscriber.setProducer(Subscriber.java:139)
at rx.internal.operators.OperatorScan$2.setProducer(OperatorScan.java:139)
at rx.Subscriber.setProducer(Subscriber.java:133)
at rx.Subscriber.setProducer(Subscriber.java:133)
at rx.internal.operators.OnSubscribeFromIterable.call(OnSubscribeFromIterable.java:47)
at rx.internal.operators.OnSubscribeFromIterable.call(OnSubscribeFromIterable.java:33)
at rx.Observable$1.call(Observable.java:144)
at rx.Observable$1.call(Observable.java:136)
at rx.Observable$1.call(Observable.java:144)
at rx.Observable$1.call(Observable.java:136)
at rx.Observable$1.call(Observable.java:144)
at rx.Observable$1.call(Observable.java:136)
at rx.Observable$1.call(Observable.java:144)
at rx.Observable$1.call(Observable.java:136)
at rx.Observable$1.call(Observable.java:144)
at rx.Observable$1.call(Observable.java:136)
at rx.Observable$1.call(Observable.java:144)
at rx.Observable$1.call(Observable.java:136)
at rx.Observable$1.call(Observable.java:144)
at rx.Observable$1.call(Observable.java:136)
at rx.Observable.subscribe(Observable.java:7284)
at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:441)
at rx.observables.BlockingObservable.single(BlockingObservable.java:340)
at EmptyTest2.test(EmptyTest2.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
तो ऐसा लगता है कि समस्या निश्चित रूप से कम करने के कार्य के उपयोग के साथ है।
@Test
public void testNoReduce()
{
Integer values[] = new Integer[]{-2, -1, 0, 1, 2, 3, 4, 5};
List<String> results = Observable.from(values).filter(new Func1<Integer, Boolean>()
{
@Override
public Boolean call(Integer integer)
{
if (integer < 0)
return true;
else
return false;
}
}).map(new Func1<Integer, String>()
{
@Override
public String call(Integer integer)
{
return String.valueOf(integer);
}
}).toList().toBlocking().first();
Iterator<String> itr = results.iterator();
StringBuilder b = new StringBuilder();
while (itr.hasNext())
{
b.append(itr.next());
if (itr.hasNext())
b.append(",");
}
System.out.println("Test NoReduce: " + b);
}
निम्न इनपुट के साथ:
Test NoReduce: -2,-1
और निम्नलिखित इनपुट के साथ:
Integer values[] = new Integer[]{-2, -1, 0, 1, 2, 3, 4, 5};
मैं निम्नलिखित परिणाम जो उम्मीद कर रहे हैं पाने के निम्नलिखित परीक्षण का मामला है कि दोनों स्थितियों संभालती देखें :
Integer values[] = new Integer[]{0, 1, 2, 3, 4, 5};
मैं निम्नलिखित उत्पादन जो उम्मीद कर रहे हैं मिलता है:
Test NoReduce:
तो, जब तक मैं पूरी तरह से गलतफहमी कुछ, एक ही रास्ता वास्तव में है कि एक फिल्टर से परिणाम जब एक नक्शे के द्वारा पीछा किया और को कम है संभाल करने के लिए एक शून्य तत्व प्रत्यक्ष कर रहा हूँ अवलोकन श्रृंखला के बाहर तर्क को कम करने के लिए। क्या आप सभी उस कथन से सहमत हैं?
अंतिम समाधान
यहाँ दोनों टॉमस ड्वोरक और डेविड Motten सुझाव को लागू करने के बाद अपने अंतिम समाधान है। मुझे लगता है कि यह समाधान उचित है।
@Test
public void testWithToList()
{
Integer values[] = new Integer[]{-2, -1, 0, 1, 2, 3, 4, 5};
Observable.from(values).filter(new Func1<Integer, Boolean>()
{
@Override
public Boolean call(Integer integer)
{
if (integer < 0)
return true;
else
return false;
}
}).toList().map(new Func1<List<Integer>, String>()
{
@Override
public String call(List<Integer> integers)
{
Iterator<Integer> intItr = integers.iterator();
StringBuilder b = new StringBuilder();
while (intItr.hasNext())
{
b.append(intItr.next());
if (intItr.hasNext())
{
b.append(",");
}
}
return b.toString();
}
}).subscribe(new Action1<String>()
{
@Override
public void call(String s)
{
System.out.println("With a toList: " + s);
}
});
}
यहां बताया गया है कि निम्न परीक्षण दिए जाने पर यह परीक्षण कैसे व्यवहार करता है।
जब एक धारा होगा कि कुछ मान फिल्टर के माध्यम से पारित दिया:
Integer values[] = new Integer[]{-2, -1, 0, 1, 2, 3, 4, 5};
परिणाम है:
With a toList: -2,-1
जब एक स्ट्रीम में कोई भी मान नहीं होगा कि दिए गए फिल्टर के माध्यम से पारित :
Integer values[] = new Integer[]{0, 1, 2, 3, 4, 5};
परिणाम है:
With a toList: <empty string>
कुछ कोड पोस्ट करें, तो हम स्टैक ट्रेस से यह अनुमान लगाने के लिए नहीं है। –
आप सही हैं मैं एक परीक्षण केस जोड़ने में विफल रहा। मैंने एक सरल जोड़ा। – babernathy