java - जावा 8 में, क्या एक बाइटस्ट्रीम क्लास है?




java-8 byte (2)

अधिकांश बाइट-संबंधी ऑपरेशन स्वचालित रूप से int में पदोन्नत हो जाते हैं। उदाहरण के लिए, आइए उस सरल विधि पर विचार करें जो byte के प्रत्येक तत्व के लिए एक byte जोड़ती है byte[] सरणी नई byte[] ByteStream byte[] ऐरे ( ByteStream लिए संभावित उम्मीदवार):

public static byte[] add(byte[] arr, byte addend) {
    byte[] result = new byte[arr.length];
    int i=0;
    for(byte b : arr) {
        result[i++] = (byte) (b+addend);
    }
    return result;
}

देखें, भले ही हम दो byte वेरिएबल्स को जोड़ते हैं, फिर भी उन्हें int चौड़ा किया जाता है और आपको परिणाम को byte वापस लाने की आवश्यकता होती है। जावा बाइटकोड में ज्यादातर byte संबंधित ऑपरेशन (एरे लोड / स्टोर और बाइट को छोड़कर) 32-बिट पूर्णांक निर्देश ( iadd , ixor , if_icmple और इसी तरह) के साथ व्यक्त किए जाते हैं। इस प्रकार व्यावहारिक रूप से यह बाइट्स को IntStream साथ ints के रूप में संसाधित करना ठीक है। हमें बस दो अतिरिक्त संचालन चाहिए:

  • byte[] सरणी से एक IntStream बनाएं (बाइट्स को बाइट्स में चौड़ा करें)
  • byte[] सरणी (byte) का उपयोग करके (byte) लिए एक IntStream लीजिए

पहला वास्तव में आसान है और इसे इस तरह लागू किया जा सकता है:

public static IntStream intStream(byte[] array) {
    return IntStream.range(0, array.length).map(idx -> array[idx]);
}

तो आप अपनी परियोजना में ऐसी स्थैतिक विधि जोड़ सकते हैं और खुश रह सकते हैं।

धारा को byte[] सरणी में एकत्रित करना अधिक मुश्किल है। मानक JDK कक्षाओं का उपयोग करना सबसे सरल उपाय है ByteArrayOutputStream :

public static byte[] toByteArray(IntStream stream) {
    return stream.collect(ByteArrayOutputStream::new, (baos, i) -> baos.write((byte) i),
            (baos1, baos2) -> baos1.write(baos2.toByteArray(), 0, baos2.size()))
            .toByteArray();
}

हालांकि यह सिंक्रनाइज़ेशन के कारण अनावश्यक ओवरहेड है। इसके अलावा आवंटन और नकल को कम करने के लिए विशेष रूप से ज्ञात लंबाई की धाराओं को संसाधित करना अच्छा होगा। फिर भी अब आप byte[] लिए स्ट्रीम एपीआई का उपयोग कर सकते हैं byte[] सरणियाँ:

public static byte[] addStream(byte[] arr, byte addend) {
    return toByteArray(intStream(arr).map(b -> b+addend));
}

मेरी StreamEx लाइब्रेरी में IntStreamEx क्लास के ये दोनों ऑपरेशन हैं जो स्टैण्डर्ड IntStream , इसलिए आप इसे इस तरह इस्तेमाल कर सकते हैं:

public static byte[] addStreamEx(byte[] arr, byte addend) {
    return IntStreamEx.of(arr).map(b -> b+addend).toByteArray();
}

आंतरिक रूप से toByteArray() विधि सरल रीसेबल बाइट बफर का उपयोग करती है और विशेष रूप से मामले को संभालती है जब धारा अनुक्रमिक होती है और लक्ष्य आकार अग्रिम में जाना जाता है।

जावा 8 Stream<T> double , int और long लिए विशेषज्ञता प्रदान करता है: क्रमशः LongStream , IntStream और LongStream । हालाँकि, मुझे दस्तावेज़ में byte लिए एक समकक्ष नहीं मिला।

क्या जावा 8 एक ByteStream क्लास प्रदान करता है?


नहीं, यह मौजूद नहीं है। दरअसल, यह स्पष्ट रूप से लागू नहीं किया गया था ताकि हर आदिम प्रकार के टन वर्गों के साथ स्ट्रीम एपीआई को अव्यवस्थित न किया जाए।

OpenJDK मेलिंग सूची में ब्रायन गोएट्ज़ के एक मेल का हवाला देते हुए:

संक्षिप्त उत्तर: नहीं।

यह इन रूपों के लिए प्रत्येक JDK पदचिह्न का एक और 100K + लायक नहीं है जो लगभग कभी नहीं उपयोग किए जाते हैं। और अगर हम उन लोगों को जोड़ते हैं, तो कोई कम, फ्लोट या बूलियन की मांग करेगा।

एक और तरीका रखो, अगर लोग जोर देते हैं कि हमारे पास सभी आदिम विशेषज्ञताएं हैं, तो हमारे पास कोई आदिम विशेषज्ञता नहीं होगी। जो यथास्थिति से भी बदतर होगी।






boxing