অ্যারে থেকে স্ট্রিমিংয়ের সময় আমি কেন স্ট্রিংয়ের সাথে পূর্ণসংখ্যার মানচিত্র রাখতে পারি না?


94

এই কোডটি কাজ করে (জাভাডকে তোলা):

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
String commaSeparatedNumbers = numbers.stream()
    .map(i -> i.toString())
    .collect(Collectors.joining(", "));

এটি একটি সংকলন করা যায় না:

int[] numbers = {1, 2, 3, 4};
String commaSeparatedNumbers = Arrays.stream(numbers)
    .map((Integer i) -> i.toString())
    .collect(Collectors.joining(", "));

আইডিইএ আমাকে জানায় আমার কাছে "ল্যাম্বডা এক্সপ্রেশনে বেমানান রিটার্ন টাইপের স্ট্রিং রয়েছে"।

কেন? এবং কিভাবে এটি ঠিক করবেন?

উত্তর:


121

Arrays.stream(int[])একটি IntStream, না একটি তৈরি করে Stream<Integer>। সুতরাং কোনও বস্তুর সাথে ম্যাপিংয়ের সময় আপনাকে ন্যায়বিচারের mapToObjপরিবর্তে কল করতে হবে ।mapint

এটি প্রত্যাশা অনুযায়ী কাজ করা উচিত:

String commaSeparatedNumbers = Arrays.stream(numbers)
    .mapToObj(i -> ((Integer) i).toString()) //i is an int, not an Integer
    .collect(Collectors.joining(", "));

যা আপনি এটি লিখতে পারেন:

String commaSeparatedNumbers = Arrays.stream(numbers)
    .mapToObj(Integer::toString)
    .collect(Collectors.joining(", "));

4
মধ্যে পার্থক্য কি IntStreamএবং Stream<Integer>?
ফ্লোরিয়ান মার্জাইন

8
@ ফ্লোরিয়ানমারগাইন আন IntStreamআদিম intমানের জন্য একটি স্ট্রিম বিশেষীকরণ । এ Stream<Integer>হ'ল একটি স্ট্রিম ধারণকারী Integerঅবজেক্ট।
অ্যালেক্সিস সি

4
@ ফ্লোরিয়ানমারগাইন IntStreamএকটি স্ট্রিম বা আদিম (অন্তর্নিহিত) যেখানে Steram<Integer>বস্তুর স্রোত। আদিম স্ট্রিমগুলির কার্য সম্পাদনের কারণে বিশেষ পদ্ধতি রয়েছে।
Assylias

7
IntStream.mapToObjএকটি IntFunction, একটি ফাংশন প্রত্যাশা করে যা একটি intমান গ্রহণ করে, তাই  .mapToObj((Integer i) -> i.toString())কাজ করে না। এটা বাঞ্ছনীয় যাহাই হউক না কেন হবে না যেমন তা থেকে একটি অপ্রয়োজনীয় রূপান্তর রয়েছে intকরার Integer। বিপরীতে, পদ্ধতিটি .mapToObj(Integer::toString)যেমন কল করবে তেমন সুন্দরভাবে কাজ করে । মনে রাখবেন যে এটি কল করার ক্ষেত্রে  এটির চেয়ে আলাদা কারণ যেটি পরে সংকলন করবে না কারণ এটি অস্পষ্ট। staticInteger.toString(int).map(Integer::toString)Stream<Integer>
হলগার

4
@ সিক: না, এ কল .map(Integer::toString)করা Stream<Integer>উভয়ের মতোই সত্যই অস্পষ্ট .map(i->i.toString())এবং .map(i->Integer.toString(i))বৈধ। তবে এটি ব্যবহার করে সহজেই সমাধানযোগ্য .map(Object::toString)
হলগার

19

Arrays.stream(numbers)IntStreamহুডের নীচে একটি তৈরি করে এবং মানচিত্রের অপারেশনটির IntStreamজন্য একটি IntUnaryOperator(যেমন একটি ফাংশন int -> int) প্রয়োজন। আপনি যে ম্যাপিং ফাংশনটি প্রয়োগ করতে চান তা এই চুক্তিকে সম্মান করে না এবং তাই সংকলনের ত্রুটি।

boxed()একটি পাওয়ার জন্য আপনাকে আগে কল করতে হবে Stream<Integer>(এটিই Arrays.asList(...).stream()প্রত্যাবর্তন করে)। তারপরে mapআপনি যেমন প্রথম স্নিপেটে করেছিলেন ঠিক তেমন কল করুন ।

মনে রাখবেন যে আপনার যদি boxed()অনুসরণ করা প্রয়োজন হয় তবে mapসম্ভবত আপনি mapToObjসরাসরি ব্যবহার করতে চান ।

সুবিধাটি হ'ল mapToObjপ্রতিটি বস্তুকে intকোনও মান বাক্স করতে হবে না Integer; আপনি অবশ্যই প্রয়োগ ম্যাপিং ফাংশন উপর নির্ভর করে; সুতরাং আমি এই বিকল্প যা যা আরও ছোট লিখতে হবে সঙ্গে যেতে হবে।


5

আপনি অ্যারেস স্ট্রিম (ইনট []] ব্যবহার করে একটি পূর্ণসংখ্যা স্ট্রিম তৈরি করতে পারেন, আপনি পছন্দ করতে mapToObjপারেন mapToObj(Integer::toString)

String csn = Arrays.stream(numbers) // your numbers array
.mapToObj(Integer::toString)
.collect(Collectors.joining(", "));

আশাকরি এটা সাহায্য করবে..


2

কোনও বক্সিং, এএফএআইকি এবং কোনও ছোট স্ট্রিংয়ের কোনও বিস্ফোরণ গাদাতে যুক্ত হয়নি:

public static void main(String[] args) {
    IntStream stream = IntStream.of(1, 2, 3, 4, 5, 6);
    String s = stream.collect(StringBuilder::new, (builder, n) -> builder.append(',').append(n), (x, y) -> x.append(',').append(y)).substring(1);
    System.out.println(s);
}

1

যদি এই নমুনা এবং প্রশ্নের উদ্দেশ্যটি কীভাবে একটি কীটস্রোতে স্ট্রিংগুলি মানচিত্র করা যায় তা উদাহরণস্বরূপ (উদাহরণস্বরূপ, স্ট্রিংগুলির অ্যারেতে সূচি অ্যাক্সেসের জন্য ints এর স্রোত ব্যবহার করে), আপনি বক্সিংও ব্যবহার করতে পারেন, তারপরে কাস্টিং একটি int (যা তারপরে অ্যারের সূচকটি অ্যাক্সেসের অনুমতি দেয়)।

int[] numbers = {0, 1, 2, 3}; 
String commaSeparatedNumbers = Arrays.stream(numbers)
    .boxed()
    .map((Integer i) -> Integer.toString((int)i))
    .collect(Collectors.joining(", "));

.Boxed () কলটি আপনার ইন্টারস্ট্রিমকে (আদিম অন্তরের স্রোতকে) একটি স্ট্রিমে রূপান্তর করে (বস্তুর স্রোত - যথা, পূর্ণসংখ্যার বস্তু) যা তারপরে কোনও অবজেক্টের (এই ক্ষেত্রে স্ট্রিং অবজেক্ট) রিটার্ন গ্রহণ করবে will তোমার ল্যাম্বদা এখানে এটি প্রদর্শনের উদ্দেশ্যে সংখ্যার কেবল একটি স্ট্রিং প্রতিনিধিত্ব, তবে এটি যেমনটি সহজেই (এবং আরও ব্যবহারিকভাবে) যে কোনও স্ট্রিং অবজেক্ট হতে পারে - যেমন স্ট্রিং অ্যারের উপাদানটি পূর্বে উল্লিখিত হয়েছে।

ভেবেছিলাম আমি আরেকটি সম্ভাবনা দেব। প্রোগ্রামিংয়ে সর্বদা একটি কার্য সম্পাদনের একাধিক উপায় থাকে। আপনি যতটা পারেন তা জানুন, তারপরে পারফরম্যান্সের বিষয়গুলি, স্বজ্ঞাততা, কোডের স্পষ্টতা, কোডিং শৈলীতে আপনার পছন্দ এবং সর্বাধিক স্ব-ডকুমেন্টিংয়ের বিষয়টি বিবেচনায় রেখে কাজের জন্য সবচেয়ে ভাল ফিট করে এমন একটি চয়ন করুন।

শুভ কোডিং!


4
আপনি অপ্রয়োজনীয় কাজ করছেন। আপনি প্রত্যেকটি intতার মোড়ক প্রকারের বাক্সে Integerফেলেছেন এবং আপনি এটির কিছুক্ষণের মধ্যেই আনবক্স করুন।
অ্যালেক্সিস সি।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.