অতিরিক্ত উদাহরণগুলির জন্য, জাভা 8 স্ট্রিম টিউটোরিয়াল থেকে সমস্ত নমুনা কোটলিনে রূপান্তরিত। প্রতিটি উদাহরণের শিরোনাম উত্স নিবন্ধ থেকে প্রাপ্ত:
স্ট্রিমগুলি কীভাবে কাজ করে
// Java:
List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");
myList.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
// C1
// C2
// Kotlin:
val list = listOf("a1", "a2", "b1", "c2", "c1")
list.filter { it.startsWith('c') }.map (String::toUpperCase).sorted()
.forEach (::println)
বিভিন্ন ধরণের স্ট্রিম # 1
// Java:
Arrays.asList("a1", "a2", "a3")
.stream()
.findFirst()
.ifPresent(System.out::println);
// Kotlin:
listOf("a1", "a2", "a3").firstOrNull()?.apply(::println)
বা, স্ট্রিংয়ে ইফপ্রেসেন্ট নামে একটি এক্সটেনশন ফাংশন তৈরি করুন:
// Kotlin:
inline fun String?.ifPresent(thenDo: (String)->Unit) = this?.apply { thenDo(this) }
// now use the new extension function:
listOf("a1", "a2", "a3").firstOrNull().ifPresent(::println)
এছাড়াও দেখুন: apply()
ফাংশন
আরও দেখুন: এক্সটেনশন ফাংশন
এটিও দেখুন: ?.
নিরাপদ কল অপারেটর এবং সাধারণভাবে অকার্যকরতা: কোটলিনে, মূল্যহীন মানগুলির সাথে সম্পর্কিত বা রেফারেন্সিং বা রূপান্তরিত করার অলৌকিক উপায় কী?
বিভিন্ন ধরণের স্ট্রিম # 2
// Java:
Stream.of("a1", "a2", "a3")
.findFirst()
.ifPresent(System.out::println);
// Kotlin:
sequenceOf("a1", "a2", "a3").firstOrNull()?.apply(::println)
বিভিন্ন ধরণের স্ট্রিম # 3
// Java:
IntStream.range(1, 4).forEach(System.out::println);
// Kotlin: (inclusive range)
(1..3).forEach(::println)
বিভিন্ন ধরণের স্ট্রিম # 4
// Java:
Arrays.stream(new int[] {1, 2, 3})
.map(n -> 2 * n + 1)
.average()
.ifPresent(System.out::println); // 5.0
// Kotlin:
arrayOf(1,2,3).map { 2 * it + 1}.average().apply(::println)
বিভিন্ন ধরণের স্ট্রিম # 5
// Java:
Stream.of("a1", "a2", "a3")
.map(s -> s.substring(1))
.mapToInt(Integer::parseInt)
.max()
.ifPresent(System.out::println); // 3
// Kotlin:
sequenceOf("a1", "a2", "a3")
.map { it.substring(1) }
.map(String::toInt)
.max().apply(::println)
বিভিন্ন ধরণের স্ট্রিম # 6
// Java:
IntStream.range(1, 4)
.mapToObj(i -> "a" + i)
.forEach(System.out::println);
// a1
// a2
// a3
// Kotlin: (inclusive range)
(1..3).map { "a$it" }.forEach(::println)
বিভিন্ন ধরণের স্ট্রিম # 7
// Java:
Stream.of(1.0, 2.0, 3.0)
.mapToInt(Double::intValue)
.mapToObj(i -> "a" + i)
.forEach(System.out::println);
// a1
// a2
// a3
// Kotlin:
sequenceOf(1.0, 2.0, 3.0).map(Double::toInt).map { "a$it" }.forEach(::println)
অর্ডার বিষয়গুলি কেন
জাভা 8 স্ট্রিম টিউটোরিয়ালটির এই বিভাগটি কোটলিন এবং জাভার ক্ষেত্রে একই।
স্ট্রিম পুনরায় ব্যবহার করা হচ্ছে
কোটলিনে এটি একাধিকবার খাওয়া যায় কিনা তা সংগ্রহের ধরণের উপর নির্ভর করে। একটি Sequence
প্রতিবারই একটি নতুন পুনরুক্তি তৈরি করে এবং যতক্ষণ না এটি "একবার ব্যবহার করুন" হিসাবে দৃ unless় প্রতিপন্ন হয় ততক্ষণে প্রতিটি বার যখন এটি করা হয় তখন এটি পুনরায় সেট করতে পারে can নিম্নলিখিত জাভা 8 প্রবাহে ব্যর্থ হলেও কোটলিনে কাজ করে:
// Java:
Stream<String> stream =
Stream.of("d2", "a2", "b1", "b3", "c").filter(s -> s.startsWith("b"));
stream.anyMatch(s -> true); // ok
stream.noneMatch(s -> true); // exception
// Kotlin:
val stream = listOf("d2", "a2", "b1", "b3", "c").asSequence().filter { it.startsWith('b' ) }
stream.forEach(::println) // b1, b2
println("Any B ${stream.any { it.startsWith('b') }}") // Any B true
println("Any C ${stream.any { it.startsWith('c') }}") // Any C false
stream.forEach(::println) // b1, b2
এবং জাভাতে একই আচরণ পেতে:
// Java:
Supplier<Stream<String>> streamSupplier =
() -> Stream.of("d2", "a2", "b1", "b3", "c")
.filter(s -> s.startsWith("a"));
streamSupplier.get().anyMatch(s -> true); // ok
streamSupplier.get().noneMatch(s -> true); // ok
সুতরাং কোটলিনে ডেটা সরবরাহকারী সিদ্ধান্ত নেয় যে এটি আবার রিসেট করতে পারে এবং কোনও নতুন পুনরাবৃত্তি সরবরাহ করতে পারে কিনা। তবে আপনি যদি ইচ্ছাকৃতভাবে একবারে Sequence
এক সময়ের পুনরাবৃত্তি সীমাবদ্ধ করতে চান তবে আপনি নীচের হিসাবে constrainOnce()
ফাংশনটি ব্যবহার করতে পারেন Sequence
:
val stream = listOf("d2", "a2", "b1", "b3", "c").asSequence().filter { it.startsWith('b' ) }
.constrainOnce()
stream.forEach(::println) // b1, b2
stream.forEach(::println) // Error:java.lang.IllegalStateException: This sequence can be consumed only once.
উন্নত অপারেশন
# 5 উদাহরণ সংগ্রহ করুন (হ্যাঁ, আমি ইতিমধ্যে অন্যান্য উত্তরে এড়িয়ে গেছি)
// Java:
String phrase = persons
.stream()
.filter(p -> p.age >= 18)
.map(p -> p.name)
.collect(Collectors.joining(" and ", "In Germany ", " are of legal age."));
System.out.println(phrase);
// In Germany Max and Peter and Pamela are of legal age.
// Kotlin:
val phrase = persons.filter { it.age >= 18 }.map { it.name }
.joinToString(" and ", "In Germany ", " are of legal age.")
println(phrase)
// In Germany Max and Peter and Pamela are of legal age.
এবং একটি পার্শ্ব নোট হিসাবে, কোটলিনে আমরা সহজ ডেটা ক্লাস তৈরি করতে পারি এবং পরীক্ষার ডেটা নীচে নীচে ইনস্ট্যান্ট করতে পারি:
// Kotlin:
// data class has equals, hashcode, toString, and copy methods automagically
data class Person(val name: String, val age: Int)
val persons = listOf(Person("Tod", 5), Person("Max", 33),
Person("Frank", 13), Person("Peter", 80),
Person("Pamela", 18))
উদাহরণ সংগ্রহ করুন # 6
// Java:
Map<Integer, String> map = persons
.stream()
.collect(Collectors.toMap(
p -> p.age,
p -> p.name,
(name1, name2) -> name1 + ";" + name2));
System.out.println(map);
// {18=Max, 23=Peter;Pamela, 12=David}
ঠিক আছে, এখানে কোটলিনের আরও সুদের মামলা। Map
সংগ্রহ / ক্রম থেকে একটি তৈরির বিভিন্নতার অন্বেষণের জন্য প্রথমে ভুল উত্তরগুলি :
// Kotlin:
val map1 = persons.map { it.age to it.name }.toMap()
println(map1)
// output: {18=Max, 23=Pamela, 12=David}
// Result: duplicates overridden, no exception similar to Java 8
val map2 = persons.toMap({ it.age }, { it.name })
println(map2)
// output: {18=Max, 23=Pamela, 12=David}
// Result: same as above, more verbose, duplicates overridden
val map3 = persons.toMapBy { it.age }
println(map3)
// output: {18=Person(name=Max, age=18), 23=Person(name=Pamela, age=23), 12=Person(name=David, age=12)}
// Result: duplicates overridden again
val map4 = persons.groupBy { it.age }
println(map4)
// output: {18=[Person(name=Max, age=18)], 23=[Person(name=Peter, age=23), Person(name=Pamela, age=23)], 12=[Person(name=David, age=12)]}
// Result: closer, but now have a Map<Int, List<Person>> instead of Map<Int, String>
val map5 = persons.groupBy { it.age }.mapValues { it.value.map { it.name } }
println(map5)
// output: {18=[Max], 23=[Peter, Pamela], 12=[David]}
// Result: closer, but now have a Map<Int, List<String>> instead of Map<Int, String>
এবং এখন সঠিক উত্তরের জন্য:
// Kotlin:
val map6 = persons.groupBy { it.age }.mapValues { it.value.joinToString(";") { it.name } }
println(map6)
// output: {18=Max, 23=Peter;Pamela, 12=David}
// Result: YAY!!
তালিকাগুলি ভেঙে ফেলার জন্য আমাদের কেবলমাত্র মিলে যাওয়া মানগুলিতে যোগ দিতে jointToString
হবে এবং Person
উদাহরণ থেকে দস্তাবেজে যেতে একটি ট্রান্সফর্মার সরবরাহ করতে হবে Person.name
।
উদাহরণ সংগ্রহ করুন # 7
ঠিক আছে, এটি সহজেই কোনও প্রথা ছাড়াই করা যায় Collector
, সুতরাং আসুন এটি কোটলিন পদ্ধতিতে সমাধান করুন, তারপরে একটি নতুন উদাহরণ তৈরি করুন যা দেখায় যে কীভাবে অনুরূপ প্রক্রিয়া করা যায় Collector.summarizingInt
যার জন্য কোটলিনে স্থানীয়ভাবে বিদ্যমান নেই।
// Java:
Collector<Person, StringJoiner, String> personNameCollector =
Collector.of(
() -> new StringJoiner(" | "), // supplier
(j, p) -> j.add(p.name.toUpperCase()), // accumulator
(j1, j2) -> j1.merge(j2), // combiner
StringJoiner::toString); // finisher
String names = persons
.stream()
.collect(personNameCollector);
System.out.println(names); // MAX | PETER | PAMELA | DAVID
// Kotlin:
val names = persons.map { it.name.toUpperCase() }.joinToString(" | ")
এটা আমার ভুল নয় যে তারা একটি তুচ্ছ উদাহরণ বেছে নিয়েছে !!! ঠিক আছে, এখানে summarizingInt
কোটলিনের জন্য একটি নতুন পদ্ধতি এবং একটি মিলের নমুনা:
সংক্ষিপ্তকরণের উদাহরণ
// Java:
IntSummaryStatistics ageSummary =
persons.stream()
.collect(Collectors.summarizingInt(p -> p.age));
System.out.println(ageSummary);
// IntSummaryStatistics{count=4, sum=76, min=12, average=19.000000, max=23}
// Kotlin:
// something to hold the stats...
data class SummaryStatisticsInt(var count: Int = 0,
var sum: Int = 0,
var min: Int = Int.MAX_VALUE,
var max: Int = Int.MIN_VALUE,
var avg: Double = 0.0) {
fun accumulate(newInt: Int): SummaryStatisticsInt {
count++
sum += newInt
min = min.coerceAtMost(newInt)
max = max.coerceAtLeast(newInt)
avg = sum.toDouble() / count
return this
}
}
// Now manually doing a fold, since Stream.collect is really just a fold
val stats = persons.fold(SummaryStatisticsInt()) { stats, person -> stats.accumulate(person.age) }
println(stats)
// output: SummaryStatisticsInt(count=4, sum=76, min=12, max=23, avg=19.0)
তবে একটি এক্সটেনশন ফাংশন তৈরি করা আরও ভাল, 2 কোটলিন স্ট্যাডলিবের শৈলীর সাথে মেলে
// Kotlin:
inline fun Collection<Int>.summarizingInt(): SummaryStatisticsInt
= this.fold(SummaryStatisticsInt()) { stats, num -> stats.accumulate(num) }
inline fun <T: Any> Collection<T>.summarizingInt(transform: (T)->Int): SummaryStatisticsInt =
this.fold(SummaryStatisticsInt()) { stats, item -> stats.accumulate(transform(item)) }
নতুন summarizingInt
ফাংশনগুলি ব্যবহার করার এখন আপনার কাছে দুটি উপায় রয়েছে :
val stats2 = persons.map { it.age }.summarizingInt()
// or
val stats3 = persons.summarizingInt { it.age }
এবং এই সমস্ত একই ফলাফল উত্পাদন করে। Sequence
যথাযথ আদিম ধরণের উপর কাজ করার জন্য আমরা এই এক্সটেনশনটি তৈরি করতে পারি ।
মজা করার জন্য, জাভা জেডিকে কোড বনাম কোটলিন কাস্টম কোডটির তুলনা করুন এই সংক্ষিপ্তকরণটি বাস্তবায়নের জন্য।
collect(Collectors.toList())
বা ব্যবহারের অনুরূপ বা অনুরূপ ছাড়া আপনার আর কোনও উপায় নেই , তবে আপনি এই সমস্যাটি হিট করতে পারেন: stackoverflow.com/a/35722167/3679676 (সমস্যাটি সহ, ইস্যু)