জাভা স্ট্রিমগুলির সাথে পূর্ণসংখ্যার একটি তালিকা যোগ করতে কিভাবে?


364

আমি পূর্ণসংখ্যার একটি তালিকা যোগ করতে চাই। এটি নিম্নলিখিত হিসাবে কাজ করে তবে সিনট্যাক্সটি ঠিক মনে হয় না। কোডটি অনুকূলিত হতে পারে?

Map<String, Integer> integers;
integers.values().stream().mapToInt(i -> i).sum();

5
"তবে সিনট্যাক্সটি ঠিক মনে হচ্ছে না" আপনাকে কী এমন মনে হয়? এটি হ'ল স্বাভাবিক প্রতিমা। mapToLongআপনার মানচিত্রের যে মান থাকতে পারে তার উপর নির্ভর করে আপনি ওভারফ্লো এড়াতে ব্যবহার করতে চান ।
অ্যালেক্সিস সি

3
@ জেবিনিজেট আমি i -> iব্যক্তিগতভাবে খুব পরিষ্কার দেখতে পাই । ঠিক আছে, হ্যাঁ আপনার জানা দরকার যে মানটি স্বয়ংক্রিয়ভাবে আনবক্সড হবে, তবে জাভা 5 এর পর থেকে এটি সত্য ...
অ্যালেক্সিস সি।

4
@AlexisC। এটি বোধগম্য কারণ এটি মানচিত্রটিইন্ট () এ গেছে এবং কারণ আমি একজন অভিজ্ঞ বিকাশকারী। তবে আমি -> আমি প্রসঙ্গ ব্যতীত দেখতে নূরের মতো। পূর্ণসংখ্যা :: ইন্টভ্যালু আরও ভার্বোজ, তবে আনবক্সিং অপারেশনটিকে সুস্পষ্ট করে তোলে।
জেবি নিজেট

1
@ জেবিনিজেট লোকেরা যে পদ্ধতিটিকে কল করে তারা প্রতিবার কল করলে তারা foo(int i)লেখেন না foo(myInteger.intValue());(বা কমপক্ষে আমি প্রত্যাশা করি না !!)। আমি আপনার সাথে একমত হয়েছি Integer::intValueযা আরও স্পষ্ট হয় তবে আমি মনে করি এটি এখানে প্রযোজ্য। লোকেরা একবারে এটি শিখতে হবে এবং তারপরে আপনি শেষ করেছেন :-)। এটি কিছু ম্যাজিক আবদ্ধতা ছিল তা পছন্দ করে না।
অ্যালেক্সিস সি

4
@JB Nizet: ভাল, i -> iকোন সমিতি এবং conceptionally মত দেখাচ্ছে, এটা হল একটি নো অপ। অবশ্যই, ফণা নীচে Integer.intValue()ডাকা হয়, কিন্তু ফণা অধীনে আরও গভীর, যে পদ্ধতি উত্স কোড এর মত দেখতে ঠিক কোন অপ-হতে পরিণত হয়। Integer::intValueবাইট কোডে একটি সিনথেটিক পদ্ধতি তৈরি না করার বোনাস পয়েন্ট রয়েছে তবে কীভাবে আপনার উত্স কোডটি সংগঠিত করবেন সে সম্পর্কে আপনার সিদ্ধান্তটি চালানো উচিত নয়।
হোলার

উত্তর:


498

এটি কাজ করবে, তবে এটি i -> iকিছু স্বয়ংক্রিয় আনবক্সিং করছে যার কারণে এটি "অদ্ভুত" বোধ করে। নীচের যে কোনওটি কাজ করবে এবং আপনার মূল সিনট্যাক্সের সাহায্যে সংকলক হুডের নীচে কী করছে তা আরও ভালভাবে ব্যাখ্যা করবে:

integers.values().stream().mapToInt(i -> i.intValue()).sum();
integers.values().stream().mapToInt(Integer::intValue).sum();

2
আমাদের যদি একটি বিগইন্টেগার থাকে :)?
GOXR3PLUS

13
একটি সরল বিকল্পBigDecimal sum = numbers.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
ম্যাথু

158

আমি আরও 2 টি বিকল্প প্রস্তাব করছি:

integers.values().stream().mapToInt(Integer::intValue).sum();
integers.values().stream().collect(Collectors.summingInt(Integer::intValue));

দ্বিতীয়টি Collectors.summingInt()সংগ্রাহক ব্যবহার করে , সেখানে একজন summingLong()সংগ্রাহকও রয়েছে যা আপনি ব্যবহার করবেন mapToLong


এবং একটি তৃতীয় বিকল্প: জাভা 8 LongAdderসমান্তরাল স্ট্রিম এবং মাল্টি-থ্রেড পরিবেশে গতি বাড়ানোর জন্য ডিজাইন করা একটি খুব কার্যকর সঞ্চালক উপস্থাপন করেছে । এখানে, এখানে উদাহরণ ব্যবহার করুন:

LongAdder a = new LongAdder();
map.values().parallelStream().forEach(a::add);
sum = a.intValue();

86

ডক্স থেকে

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

অবশ্যই, এই জাতীয় ক্রিয়াকলাপগুলি সহজেই সাধারণ সিক্যুয়াল লুপ হিসাবে প্রয়োগ করা যেতে পারে:

int sum = 0;
for (int x : numbers) {
   sum += x;
}

যাইহোক, উপরোক্ত মত মিউটেশন জমে কমানোর অপারেশনকে পছন্দ করার ভাল কারণ রয়েছে। কেবল হ্রাস "আরও বিমূর্ত" নয় - এটি পৃথক উপাদানগুলির চেয়ে সামগ্রিকভাবে স্রোতে পরিচালিত হয় - তবে সঠিকভাবে নির্মিত কমানো অপারেশন সহজাতভাবে সমান্তরাল হয়, যতক্ষণ না উপাদানগুলি প্রক্রিয়া করতে ব্যবহৃত ফাংশন (গুলি) সংঘবদ্ধ হয় এবং রাষ্ট্রহীন। উদাহরণস্বরূপ, সংখ্যার একটি স্ট্রিম দেওয়া যার জন্য আমরা যোগফলটি খুঁজতে চাই, আমরা লিখতে পারি:

int sum = numbers.stream().reduce(0, (x,y) -> x+y);

বা:

int sum = numbers.stream().reduce(0, Integer::sum);

এই হ্রাস অপারেশনগুলি প্রায় কোনও পরিবর্তন ছাড়াই সমান্তরালে নিরাপদে চলতে পারে:

int sum = numbers.parallelStream().reduce(0, Integer::sum);

সুতরাং, একটি মানচিত্রের জন্য আপনি ব্যবহার করবেন:

integers.values().stream().mapToInt(i -> i).reduce(0, (x,y) -> x+y);

বা:

integers.values().stream().reduce(0, Integer::sum);

2
ওপি যা আছে তা আরও ভাল এবং আরও পরিষ্কার। এই কোডটি আনবক্সিং এবং বক্সিং অপারেশনগুলির পুরো লোটকে জড়িত করবে।
জেবি নিজেট

1
@ জেবিনিজেট অব্যাহত বিশ্লেষণ বক্সিংটি সরিয়ে না দিলে। এটি কিনা তা দেখতে আপনাকে চেষ্টা করতে হবে।
পিটার লরি

6
(x, y) -> x + y এর x এবং y আনবক্স করতে হবে, তাদের যোগফল করতে হবে এবং তারপরে ফলাফলটি বাক্সে বসাতে হবে। এবং স্ট্রিমের পরবর্তী উপাদানটির সাথে ফলাফল যুক্ত করতে আবার শুরু করুন এবং বারবার।
জেবি নিজত

3
পূর্ণসংখ্যা :: যোগফল একই সমস্যায় ভুগছে। এবং যদি আপনি মান্টটোয়েন্ট () ব্যবহার করে কোনও ইন্টারস্ট্রিম রাখেন, তার উপর যোগফলকে () কল করা হ্রাস () কল করার চেয়ে সহজ।
জেবি নিজেট

3
Docs.oracle.com/javase/8/docs/api/java/lang/… দেখুন । পূর্ণসংখ্যা.সাম () এর দুটি আর্গুমেন্ট টাইপ ইন্টের। সুতরাং স্ট্রিমের দুটি পূর্ণসংখ্যার পদ্ধতিটিতে আর্গুমেন্ট হিসাবে পাস করার জন্য অবশ্যই আনবক্স করা উচিত। পদ্ধতিটি কোন পূর্বাবস্থায় ফিরে আসে, তবে হ্রাস () একটি বাইনারিওপ্রেটার <Integer> কে তর্ক হিসাবে গ্রহণ করে, যা এভাবে পূর্ণসংখ্যা দেয়। সুতরাং যোগফলের ফলাফলটি পূর্ণসংখ্যায় বক্স করতে হবে।
জেবি নিজেট

28

আপনি হ্রাস পদ্ধতি ব্যবহার করতে পারেন:

long sum = result.stream().map(e -> e.getCreditAmount()).reduce(0L, (x, y) -> x + y);

অথবা

long sum = result.stream().map(e -> e.getCreditAmount()).reduce(0L, Integer::sum);

9
ইতিমধ্যেই যেমন সঁচায়ক জন্য int, এটাInteger::sum
অ্যালেক্স Salauyou

1
আপনি দীর্ঘ ফিরে আসছেন, সুতরাং এটির Long::sumচেয়ে ভাল হবে Integer::sum
আন্দ্রেই দামিয়ান-ফেকেতে 12'19

16

আপনি reduce()পূর্ণসংখ্যার একটি তালিকা যোগ করতে ব্যবহার করতে পারেন ।

int sum = integers.values().stream().reduce(0, Integer::sum);

11

পূর্ণসংখ্যার তালিকা যুক্ত করতে আপনি সংগ্রহ পদ্ধতিটি ব্যবহার করতে পারেন।

List<Integer> list = Arrays.asList(2, 4, 5, 6);
int sum = list.stream().collect(Collectors.summingInt(Integer::intValue));

6

এটি intটাইপ অ্যারের যোগফলের সংক্ষিপ্ততম উপায় হবে ( longঅ্যারের LongStreamজন্য, doubleঅ্যারের জন্য DoubleStreamএবং আরও কিছু)। সমস্ত আদিম পূর্ণসংখ্যার বা ভাসমান পয়েন্টের ধরণের Streamবাস্তবায়ন যদিও নেই।

IntStream.of(integers).sum();

দুর্ভাগ্যক্রমে আমাদের কোনও ইন-অ্যারে নেই। সুতরাং IntStream.of()এই সমস্যার জন্য কাজ করবে না, যদি না আমরা এরকম কিছু ভ্রূকুটো তৈরি করি:IntStream.of( integers.values().stream().mapToInt( Integer::intValue ).toArray() ).sum();
কাপলান

প্রয়োজন নেই, এটি যথেষ্ট হবে integers.values().stream().mapToInt( Integer::intValue ).sum()
সচিথ ডিকওয়েলা

3

এই তালিকায় যাদের অবজেক্ট রয়েছে তাদের সহায়তা করুন।

যদি আপনার কাছে অবজেক্টের একটি তালিকা থাকে এবং নীচে এই অবজেক্টের নির্দিষ্ট ক্ষেত্রগুলি যোগ করতে চান use

List<ResultSom> somList = MyUtil.getResultSom();
BigDecimal result= somList.stream().map(ResultSom::getNetto).reduce(
                                             BigDecimal.ZERO, BigDecimal::add);

ধন্যবাদ এটি আমার একটি
দৃশ্যে

1

আমি পূর্ণসংখ্যার একটি তালিকা ঘোষণা করেছি।

ArrayList<Integer> numberList = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));

আপনি নীচে এই বিভিন্ন উপায়ে ব্যবহার করার চেষ্টা করতে পারেন।

ব্যবহার mapToInt

int sum = numberList.stream().mapToInt(Integer::intValue).sum();

ব্যবহার summarizingInt

int sum = numberList.stream().collect(Collectors.summarizingInt(Integer::intValue)).getSum();

ব্যবহার reduce

int sum = numberList.stream().reduce(Integer::sum).get().intValue();

-1
class Pojo{
    int num;

    public Pojo(int num) {
        super();
        this.num = num;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }
}

List<Pojo> list = new ArrayList<Pojo>();
            list.add(new Pojo(1));
            list.add(new Pojo(5));
            list.add(new Pojo(3));
            list.add(new Pojo(4));
            list.add(new Pojo(5));

            int totalSum = list.stream().mapToInt(pojo -> pojo.getNum()).sum();
            System.out.println(totalSum);

-1

বেশিরভাগ দিকই coveredাকা থাকে। তবে পূর্ণসংখ্যা, লং (যার জন্য বিশেষত স্ট্রিম সমর্থন ইতিমধ্যে উপস্থিত) ব্যতীত অন্যান্য ডেটা ধরণের সংহতকরণ সন্ধানের প্রয়োজন হতে পারে। যেমন বিগইন্টিজারের সাথে স্ট্র্যাম এ জাতীয় ধরণের জন্য আমরা কম অপারেশন যেমন ব্যবহার করতে পারি

list.stream ()। হ্রাস করুন ((bigInteger1, bigInteger2) -> bigInteger1.add (bigInteger2))

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