জাভা 8-তে সূচকগুলি সহ কোনও স্ট্রিমের উপরে পুনরাবৃত্তি করার কোনও সংক্ষিপ্ত উপায় আছে?


382

স্ট্রিমের সূচকটিতে অ্যাক্সেস থাকা অবস্থায় কোনও স্ট্রিমের পুনরাবৃত্তি করার কোনও সংক্ষিপ্ত উপায় আছে কি?

String[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};

List<String> nameList;
Stream<Integer> indices = intRange(1, names.length).boxed();
nameList = zip(indices, stream(names), SimpleEntry::new)
        .filter(e -> e.getValue().length() <= e.getKey())
        .map(Entry::getValue)
        .collect(toList());

যা সেখানে দেওয়া লিনকু উদাহরণের তুলনায় বরং হতাশাব্যঞ্জক বলে মনে হচ্ছে

string[] names = { "Sam", "Pamela", "Dave", "Pascal", "Erik" };
var nameList = names.Where((c, index) => c.Length <= index + 1).ToList();

আরও সংক্ষিপ্ত উপায় আছে?

আরও মনে হচ্ছে জিপটি সরানো হয়েছে বা সরানো হয়েছে ...


2
কী intRange()? জাভা 8 এ এখন পর্যন্ত এই পদ্ধতিটি পুরোপুরি আসে নি।
রোহিত জৈন

@ রোহিতজাইন সম্ভবত একটি IntStream.rangeClosed(x, y)
Assylias

2
পার্শ্ব প্রতিক্রিয়া হিসাবে, চ্যালেঞ্জ 4 আরও ভাল দেখায় (আইএমও)List<String> allCities = map.values().stream().flatMap(list -> list.stream()).collect(Collectors.toList());
Assylias

3
হ্যাঁ, zipসরানো হয়েছে, পরীক্ষামূলক দুই মূল্যবান স্ট্রিম বিভিন্ন নামক সহ BiStreamবা MapStream। মূল সমস্যাটি হ'ল জাভাটি কার্যকরভাবে এটি করার জন্য কাঠামোগত-টাইপযুক্ত জোড় (বা টিপল) প্রকারের প্রয়োজন। একটির অভাব, জেনেরিক জোড় বা টিপল ক্লাস তৈরি করা সহজ - এটি বহুবার করা হয়েছে - তবে তারা সমস্ত একই ধরণের মুছে দেয়।
স্টুয়ার্ট

3
ওহ, জেনেরিক পেয়ার বা টুপল ক্লাসের সাথে আর একটি সমস্যা হ'ল এর জন্য সমস্ত আদিমকে বক্স করা দরকার।
স্টুয়ার্ট

উত্তর:


435

শুদ্ধতম উপায় হ'ল সূচকগুলির একটি প্রবাহ থেকে শুরু করা:

String[] names = {"Sam", "Pamela", "Dave", "Pascal", "Erik"};
IntStream.range(0, names.length)
         .filter(i -> names[i].length() <= i)
         .mapToObj(i -> names[i])
         .collect(Collectors.toList());

ফলাফলের তালিকায় কেবল "এরিক" রয়েছে।


একটি বিকল্প যা আপনাকে লুপগুলির জন্য অভ্যস্ত যখন বেশি পরিচিত দেখায় তা হ'ল একটি পরিবর্তনীয় অবজেক্টটি ব্যবহার করে একটি অ্যাডহক কাউন্টার বজায় রাখা, উদাহরণস্বরূপ AtomicInteger:

String[] names = {"Sam", "Pamela", "Dave", "Pascal", "Erik"};
AtomicInteger index = new AtomicInteger();
List<String> list = Arrays.stream(names)
                          .filter(n -> n.length() <= index.incrementAndGet())
                          .collect(Collectors.toList());

নোট করুন যে সমান্তরাল স্ট্রিমের উপরের পদ্ধতিটি ব্যবহারটি ভাঙ্গতে পারে কারণ আইটেমগুলি "ক্রমে" প্রক্রিয়াকরণ করা হবে না


28
এটমিক্স ব্যবহার করা সমান্তরাল স্ট্রিমগুলির সাথে সমস্যাযুক্ত। প্রথমত, উপাদানগুলির প্রক্রিয়াকরণের ক্রমটি প্রাথমিক অ্যারেতে উপাদানগুলির ক্রম হিসাবে একই হয় না। সুতরাং, পারমাণবিক ব্যবহার করে নির্ধারিত "সূচক" সম্ভবত প্রকৃত অ্যারে সূচকের সাথে মেলে না। দ্বিতীয়ত, পারমাণবিকতা থ্রেড-নিরাপদ থাকাকালীন, আপনি পারমাণবিকতা আপডেট করে একাধিক থ্রেডের মধ্যে বিরোধের মুখোমুখি হতে পারেন, সমান্তরালতার পরিমাণকে হ্রাস করে।
স্টুয়ার্ট

1
আমি @ এ্যাসিলিয়াসের মতো একটি সমাধান তৈরি করেছি। উল্লিখিত সমান্তরাল প্রবাহের সাথে সমস্যার সমাধানের জন্য @ স্টার্টমার্কস, আমি প্রথমে একটি প্রদত্ত সমান্তরাল স্ট্রিম অনুক্রমিক তৈরি করেছি, ম্যাপিংটি সম্পাদন করব এবং সমান্তরাল অবস্থাটি পুনরুদ্ধার করব। public static <T> Stream<Tuple2<Integer, T>> zipWithIndex(Stream<T> stream) { final AtomicInteger index = new AtomicInteger(); final Function<T, Tuple2<Integer, T>> zipper = e -> Tuples.of(index.getAndIncrement(), e); if (stream.isParallel()) { return stream.sequential().map(zipper).parallel(); } else { return stream.map(zipper); } }
ড্যানিয়েল ডায়েটরিচ

4
@ ড্যানিয়েলডিট্রিচ যদি আপনি মনে করেন যে এটি প্রশ্নটির সমাধান করে তবে আপনাকে মন্তব্য করার পরিবর্তে উত্তর হিসাবে পোস্ট করা উচিত (এবং কোডটি আরও পাঠযোগ্য হবে!)।
Assylias

3
@ ড্যানিয়েলডিট্রিচ দুঃখিত, আমি যদি সেই কোডটি সঠিকভাবে পড়ছি তবে এটি কার্যকর হবে না। সমান্তরাল বনাম সিক্যুয়ালিলে চলমান পাইপলাইনের বিভিন্ন বিভাগ থাকতে পারে না। টার্মিনাল ক্রিয়াকলাপ শুরু হলে কেবল সর্বশেষ parallelবা sequentialসম্মানিত।
স্টুয়ার্ট

4
ন্যায়বিচারের স্বার্থে @ স্টুয়ার্টের উত্তর থেকে "সবচেয়ে পরিষ্কার উপায়" চুরি হয়েছিল।
ভাদজিম

70

জাভা 8 স্ট্রিম এপিআই তে স্ট্রিম উপাদানগুলির সূচক পাওয়ার পাশাপাশি স্ট্রিপগুলি একসাথে জিপ করার ক্ষমতাও নেই। এটি দুর্ভাগ্যজনক, কারণ এটি নির্দিষ্ট অ্যাপ্লিকেশনগুলিকে (লিনকুই চ্যালেঞ্জের মতো) অন্যরকমের চেয়ে বেশি কঠিন করে তোলে।

তবে প্রায়শই কাজের ক্ষেত্র রয়েছে। সাধারণত এটি পূর্ণসংখ্যা পরিসীমা সহ স্ট্রিম "ড্রাইভিং" করে এবং মূল উপাদানগুলি প্রায়শই একটি অ্যারেতে বা সূচী দ্বারা অ্যাক্সেসযোগ্য সংগ্রহের মধ্যে থাকে সে সুযোগটি গ্রহণ করে এটি করা যেতে পারে। উদাহরণস্বরূপ, চ্যালেঞ্জ 2 সমস্যাটি এভাবে সমাধান করা যেতে পারে:

String[] names = {"Sam", "Pamela", "Dave", "Pascal", "Erik"};

List<String> nameList =
    IntStream.range(0, names.length)
        .filter(i -> names[i].length() <= i)
        .mapToObj(i -> names[i])
        .collect(toList());

আমি উপরে উল্লিখিত হিসাবে, এই তথ্য উত্স (নাম অ্যারে) সরাসরি সূচকযোগ্য যে সুবিধা গ্রহণ করে। এটি না থাকলে এই কৌশলটি কাজ করবে না।

আমি স্বীকার করব যে এটি চ্যালেঞ্জ ২ এর উদ্দেশ্য পূরণ করে না 2 তবুও এটি সমস্যাটি যথাযথভাবে কার্যকরভাবে সমাধান করে।

সম্পাদনা

আমার আগের কোড উদাহরণটি flatMapফিল্টার এবং মানচিত্রের ক্রিয়াকলাপগুলিকে ফিউজ করতে ব্যবহৃত হয়েছিল, তবে এটি জটিল ছিল এবং কোনও সুবিধা দেয়নি। আমি হোলারের মন্তব্য অনুসারে উদাহরণ আপডেট করেছি।


7
কীভাবে IntStream.range(0, names.length).filter(i->names[i].length()<=i).mapToObj(i->names[i])? এটি বক্সিং ছাড়াই কাজ করে ...
হোলার

1
হুঁ, হ্যাঁ, কেন আমি flatMapযেভাবেই আমার ব্যবহারের প্রয়োজন মনে করেছি ?
স্টুয়ার্ট

2
অবশেষে এটি পুনরায় দেখা হচ্ছে ... আমি সম্ভবত flatMapএটি ব্যবহার করেছি কারণ এটি ছাঁটাই করে একটি ফিল্টারিং এবং ম্যাপিং অপারেশনটিকে একটি একক ক্রিয়াকলাপে রূপ দেয়, তবে এটি সত্যিই কোনও সুবিধা দেয় না। আমি উদাহরণটি সম্পাদনা করব।
স্টুয়ার্ট 16

স্ট্রিম.ওফ (অ্যারে) একটি অ্যারের জন্য একটি স্ট্রিম ইন্টারফেস তৈরি করবে। কার্যকরভাবে এটিকে Stream.of( names ).filter( n -> n.length() <= 1).collect( Collectors.toList() );কম আনবক্সিং করা, এবং কম মেমরি বরাদ্দ করা; যেহেতু আমরা আর কোনও সীমাবদ্ধ স্ট্রিম তৈরি করছি না।
কোড আইজ

44

21 থেকে পেয়ারা, আপনি ব্যবহার করতে পারেন

Streams.mapWithIndex()

উদাহরণ ( অফিসিয়াল ডক থেকে ):

Streams.mapWithIndex(
    Stream.of("a", "b", "c"),
    (str, index) -> str + ":" + index)
) // will return Stream.of("a:0", "b:1", "c:2")

3
এছাড়াও, পেয়ারা লোকেরা এখনও ইচ্ছুক ইন্ডেক্সের জন্য কোনও কার্যকারিতা গ্রহণের পরিবর্তে (গ্রাহক গ্রহণের জন্য) প্রয়োগ করেনি, তবে এটি একটি নির্ধারিত সমস্যা: github.com/google/guava/issues/2913
জন গ্লাসমিয়ার

25

আমি আমার প্রকল্পে নিম্নলিখিত সমাধান ব্যবহার করেছি। আমি মনে করি পরিবর্তনীয় বস্তু বা পূর্ণসংখ্যার ব্যাপ্তি ব্যবহার করার চেয়ে এটি ভাল।

import java.util.*;
import java.util.function.*;
import java.util.stream.Collector;
import java.util.stream.Collector.Characteristics;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import static java.util.Objects.requireNonNull;


public class CollectionUtils {
    private CollectionUtils() { }

    /**
     * Converts an {@link java.util.Iterator} to {@link java.util.stream.Stream}.
     */
    public static <T> Stream<T> iterate(Iterator<? extends T> iterator) {
        int characteristics = Spliterator.ORDERED | Spliterator.IMMUTABLE;
        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, characteristics), false);
    }

    /**
     * Zips the specified stream with its indices.
     */
    public static <T> Stream<Map.Entry<Integer, T>> zipWithIndex(Stream<? extends T> stream) {
        return iterate(new Iterator<Map.Entry<Integer, T>>() {
            private final Iterator<? extends T> streamIterator = stream.iterator();
            private int index = 0;

            @Override
            public boolean hasNext() {
                return streamIterator.hasNext();
            }

            @Override
            public Map.Entry<Integer, T> next() {
                return new AbstractMap.SimpleImmutableEntry<>(index++, streamIterator.next());
            }
        });
    }

    /**
     * Returns a stream consisting of the results of applying the given two-arguments function to the elements of this stream.
     * The first argument of the function is the element index and the second one - the element value. 
     */
    public static <T, R> Stream<R> mapWithIndex(Stream<? extends T> stream, BiFunction<Integer, ? super T, ? extends R> mapper) {
        return zipWithIndex(stream).map(entry -> mapper.apply(entry.getKey(), entry.getValue()));
    }

    public static void main(String[] args) {
        String[] names = {"Sam", "Pamela", "Dave", "Pascal", "Erik"};

        System.out.println("Test zipWithIndex");
        zipWithIndex(Arrays.stream(names)).forEach(entry -> System.out.println(entry));

        System.out.println();
        System.out.println("Test mapWithIndex");
        mapWithIndex(Arrays.stream(names), (Integer index, String name) -> index+"="+name).forEach((String s) -> System.out.println(s));
    }
}

+1 - এমন একটি ফাংশন বাস্তবায়িত করতে সক্ষম হয়েছিল যা প্রতিটি এন সূচক ব্যবহার করে একটি উপাদানকে "সন্নিবেশ" করে StreamSupport.stream()এবং একটি কাস্টম পুনরাবৃত্তিকে সক্ষম করে।
আছ

13

প্রোটনপ্যাক ছাড়াও, জুও'র সেক এই কার্যকারিতা সরবরাহ করে (এবং এক্সটেনশন লাইব্রেরি দ্বারা এটি নির্মিত সাইক্লোপস-রিএ্যাক্টের মতো , আমি এই লাইব্রেরির লেখক)।

Seq.seq(Stream.of(names)).zipWithIndex()
                         .filter( namesWithIndex -> namesWithIndex.v1.length() <= namesWithIndex.v2 + 1)
                         .toList();

সেক কেবল সিক.ওফ (নাম) সমর্থন করে এবং কভারগুলির নীচে জেডিকে স্ট্রিম তৈরি করবে।

সরল-প্রতিক্রিয়া সমতুল্য একইভাবে দেখতে হবে

 LazyFutureStream.of(names)
                 .zipWithIndex()
                 .filter( namesWithIndex -> namesWithIndex.v1.length() <= namesWithIndex.v2 + 1)
                 .toList();

সাধারণ-প্রতিক্রিয়া সংস্করণটি অ্যাসিনক্রোনাস / সমবর্তী প্রক্রিয়াকরণের জন্য আরও উপযুক্ত।


জন আমি আজ আপনার লাইব্রেরি দেখেছি, আমি বিস্মিত এবং বিভ্রান্ত উভয়ই।
GOXR3PLUS

12

সম্পূর্ণতার জন্য এখানে আমার স্ট্রিমএক্স লাইব্রেরির সাথে জড়িত সমাধান :

String[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
EntryStream.of(names)
    .filterKeyValue((idx, str) -> str.length() <= idx+1)
    .values().toList();

এখানে আমরা একটি তৈরি EntryStream<Integer, String>যা প্রসারিত Stream<Entry<Integer, String>>এবং মত কিছু নির্দিষ্ট অপারেশন যোগ filterKeyValueবা values। এছাড়াও toList()শর্টকাট ব্যবহার করা হয়।


মহান কাজ; এখানে একটি শর্টকাট আছে .forEach(entry -> {}) ?
স্টিভ ওহ

2
@ স্টিও ওহ, আমি যদি আপনাকে সঠিকভাবে প্রশ্নটি বুঝতে পারি তবে হ্যাঁ, আপনি লিখতে পারেন .forKeyValue((key, value) -> {})
তাগীর ভালিভ

8

তালিকাটি বা অ্যারে দিয়ে স্ট্রিম তৈরি হওয়ার পরে আমি সমাধানগুলি এখানে পেয়েছি (এবং আপনি আকারটি জানেন)। তবে স্ট্রিম যদি অজানা আকারের হয়? এক্ষেত্রে এই রূপটি ব্যবহার করে দেখুন:

public class WithIndex<T> {
    private int index;
    private T value;

    WithIndex(int index, T value) {
        this.index = index;
        this.value = value;
    }

    public int index() {
        return index;
    }

    public T value() {
        return value;
    }

    @Override
    public String toString() {
        return value + "(" + index + ")";
    }

    public static <T> Function<T, WithIndex<T>> indexed() {
        return new Function<T, WithIndex<T>>() {
            int index = 0;
            @Override
            public WithIndex<T> apply(T t) {
                return new WithIndex<>(index++, t);
            }
        };
    }
}

ব্যবহার:

public static void main(String[] args) {
    Stream<String> stream = Stream.of("a", "b", "c", "d", "e");
    stream.map(WithIndex.indexed()).forEachOrdered(e -> {
        System.out.println(e.index() + " -> " + e.value());
    });
}

6

একটি তালিকা দিয়ে আপনি চেষ্টা করতে পারেন

List<String> strings = new ArrayList<>(Arrays.asList("First", "Second", "Third", "Fourth", "Fifth")); // An example list of Strings
strings.stream() // Turn the list into a Stream
    .collect(HashMap::new, (h, o) -> h.put(h.size(), o), (h, o) -> {}) // Create a map of the index to the object
        .forEach((i, o) -> { // Now we can use a BiConsumer forEach!
            System.out.println(String.format("%d => %s", i, o));
        });

আউটপুট:

0 => First
1 => Second
2 => Third
3 => Fourth
4 => Fifth

1
আসলে একটি দুর্দান্ত ধারণা, তবে স্ট্রিংস :: সূচিপত্র কিছুটা ব্যয়বহুল হতে পারে। পরিবর্তে আমার পরামর্শটি ব্যবহার করুন: .collect (হাশম্যাপ :: নতুন, (এইচ, গুলি) -> এইচ.পুট (এইচ.সাইজ (), গুলি), (এইচ, এস) -> {}) । আপনি সূচক তৈরি করতে কেবল আকার () পদ্ধতিটি ব্যবহার করতে পারেন।
gil.fernandes

@ gil.fernandes পরামর্শ দেওয়ার জন্য আপনাকে ধন্যবাদ। আমি সম্পাদনা করব।
V0idst4r

3

Streamসূচীতে অ্যাক্সেস থাকা সত্ত্বেও পুনরাবৃত্তি করার কোনও উপায় নেই কারণ Streamএটি কোনওর মতো নয় Collection। A Streamকেবলমাত্র এক জায়গা থেকে অন্য জায়গায় ডেটা বহন করার জন্য পাইপলাইন যা নথিতে বলা আছে :

স্টোরেজ নেই। একটি স্ট্রিম এমন কোনও ডেটা স্ট্রাকচার নয় যা উপাদানগুলি সঞ্চয় করে; পরিবর্তে, তারা গণনামূলক ক্রিয়াকলাপের পাইপলাইনের মাধ্যমে কোনও উত্স (যা কোনও ডেটা স্ট্রাকচার, একটি জেনারেটর, একটি আইও চ্যানেল ইত্যাদি) হতে মান বহন করে।

অবশ্যই, আপনি আপনার প্রশ্নটিতে ইঙ্গিত দিচ্ছেন বলে মনে হচ্ছে, আপনি সর্বদা আপনার এটিকে রূপান্তর করতে Stream<V>পারেন Collection<V>, যেমন একটি List<V>, যাতে আপনার সূচকগুলিতে অ্যাক্সেস থাকবে।


2
এটি অন্যান্য ভাষা / সরঞ্জামগুলিতে উপলব্ধ। এটি কেবল মানচিত্রের ক্রিয়াকলাপে একটি ইনক্রিমেন্টিং মান দেওয়া হয়েছে
লি ক্যাম্পবেল

ডকুমেন্টেশনের সাথে আপনার লিঙ্কটি নষ্ট হয়ে গেছে।
উসমান মুতাওয়াকিল

3

সঙ্গে https://github.com/poetix/protonpack তোমার দর্শন লগ করা যে জিপ করতে পারেন:

String[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};

List<String> nameList;
Stream<Integer> indices = IntStream.range(0, names.length).boxed(); 

nameList = StreamUtils.zip(indices, stream(names),SimpleEntry::new)
        .filter(e -> e.getValue().length() <= e.getKey()).map(Entry::getValue).collect(toList());                   

System.out.println(nameList);

3

যদি আপনি কোনও তৃতীয় পক্ষের লাইব্রেরিটি ব্যবহার করতে আপত্তি করেন না তবে Eclipse সংগ্রহে রয়েছে zipWithIndexএবং এটি forEachWithIndexবিভিন্ন ধরণের ব্যবহারের জন্য উপলব্ধ। JDK ধরণ এবং Eclipse সংগ্রহের ধরণের উভয় প্রকারের জন্য এই চ্যালেঞ্জের সমাধানগুলির একটি সেট zipWithIndex

String[] names = { "Sam", "Pamela", "Dave", "Pascal", "Erik" };
ImmutableList<String> expected = Lists.immutable.with("Erik");
Predicate<Pair<String, Integer>> predicate =
    pair -> pair.getOne().length() <= pair.getTwo() + 1;

// JDK Types
List<String> strings1 = ArrayIterate.zipWithIndex(names)
    .collectIf(predicate, Pair::getOne);
Assert.assertEquals(expected, strings1);

List<String> list = Arrays.asList(names);
List<String> strings2 = ListAdapter.adapt(list)
    .zipWithIndex()
    .collectIf(predicate, Pair::getOne);
Assert.assertEquals(expected, strings2);

// Eclipse Collections types
MutableList<String> mutableNames = Lists.mutable.with(names);
MutableList<String> strings3 = mutableNames.zipWithIndex()
    .collectIf(predicate, Pair::getOne);
Assert.assertEquals(expected, strings3);

ImmutableList<String> immutableNames = Lists.immutable.with(names);
ImmutableList<String> strings4 = immutableNames.zipWithIndex()
    .collectIf(predicate, Pair::getOne);
Assert.assertEquals(expected, strings4);

MutableList<String> strings5 = mutableNames.asLazy()
    .zipWithIndex()
    .collectIf(predicate, Pair::getOne, Lists.mutable.empty());
Assert.assertEquals(expected, strings5);

forEachWithIndexপরিবর্তে ব্যবহার করে একটি সমাধান এখানে ।

MutableList<String> mutableNames =
    Lists.mutable.with("Sam", "Pamela", "Dave", "Pascal", "Erik");
ImmutableList<String> expected = Lists.immutable.with("Erik");

List<String> actual = Lists.mutable.empty();
mutableNames.forEachWithIndex((name, index) -> {
        if (name.length() <= index + 1)
            actual.add(name);
    });
Assert.assertEquals(expected, actual);

যদি আপনি উপরের বেনামে অভ্যন্তরীণ ক্লাসে ল্যাম্বডাস পরিবর্তন করেন তবে এই সমস্ত কোড উদাহরণ জাভা 5 - 7 এও কাজ করবে।

দ্রষ্টব্য: আমি গ্রহগ্রাহ সংগ্রহের প্রতিশ্রুতিবদ্ধ


2

যদি আপনি ভাভর (পূর্বে জাভাসলং নামে পরিচিত) ব্যবহার করে থাকেন তবে আপনি উত্সর্গীকৃত পদ্ধতিটি উত্তোলন করতে পারেন:

Stream.of("A", "B", "C")
  .zipWithIndex();

আমরা যদি সামগ্রীটি প্রিন্ট করি তবে আমরা আকর্ষণীয় কিছু দেখতে পাব:

Stream((A, 0), ?)

এটি কারণ Streamsঅলস এবং স্ট্রিমের পরবর্তী আইটেমগুলি সম্পর্কে আমাদের কোনও ধারণা নেই।


1

আপনি যদি কোনও শিকারীর উপর ভিত্তি করে একটি সূচক পাওয়ার চেষ্টা করছেন তবে এটি চেষ্টা করুন:

যদি আপনি কেবল প্রথম সূচকটি সম্পর্কে যত্নশীল হন:

OptionalInt index = IntStream.range(0, list.size())
    .filter(i -> list.get(i) == 3)
    .findFirst();

অথবা আপনি যদি একাধিক সূচী খুঁজতে চান:

IntStream.range(0, list.size())
   .filter(i -> list.get(i) == 3)
   .collect(Collectors.toList());

যোগ .orElse(-1);ক্ষেত্রে আপনি একটি মান ফেরত পাঠাতে যদি এটা সেটা খুঁজে না চান।


1

AbacusUtil দ্বারা কোড এখানে

Stream.of(names).indexed()
      .filter(e -> e.value().length() <= e.index())
      .map(Indexed::value).toList();

প্রকাশ : আমি অ্যাবাকাসটিলের বিকাশকারী।


1

আপনি IntStream.iterate()সূচক পেতে ব্যবহার করতে পারেন :

String[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
List<String> nameList = IntStream.iterate(0, i -> i < names.length, i -> i + 1)
        .filter(i -> names[i].length() <= i)
        .mapToObj(i -> names[i])
        .collect(Collectors.toList());

এটি কেবল জাভা 9 এর জন্য জাভা 8-র উপরে কাজ করে আপনি এটি ব্যবহার করতে পারেন:

String[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
List<String> nameList = IntStream.iterate(0, i -> i + 1)
        .limit(names.length)
        .filter(i -> names[i].length() <= i)
        .mapToObj(i -> names[i])
        .collect(Collectors.toList());

0

নীচের উদাহরণে আমার যেমন করণীয় প্রয়োজন ততই সূচককে encapsulate করতে আপনি একটি স্থিতিশীল অভ্যন্তর শ্রেণি তৈরি করতে পারেন:

static class Indexer {
    int i = 0;
}

public static String getRegex() {
    EnumSet<MeasureUnit> range = EnumSet.allOf(MeasureUnit.class);
    StringBuilder sb = new StringBuilder();
    Indexer indexer = new Indexer();
    range.stream().forEach(
            measureUnit -> {
                sb.append(measureUnit.acronym);
                if (indexer.i < range.size() - 1)
                    sb.append("|");

                indexer.i++;
            }
    );
    return sb.toString();
}

0

এই প্রশ্নটি ( প্রথম উপাদানটির সাথে মিলে যাওয়া বুলিয়ানের সূচক পাওয়ার উপায় ) বর্তমান প্রশ্নটিকে একটি সদৃশ হিসাবে চিহ্নিত করেছে, তাই আমি তার উত্তর এখানে দিতে পারি না; আমি এখানে এটি উত্তর দিচ্ছি।

বাহ্যিক লাইব্রেরির প্রয়োজন নেই এমন ম্যাচিং সূচকটি পেতে এখানে একটি জেনেরিক সমাধান।

যদি আপনার একটি তালিকা থাকে।

public static <T> int indexOf(List<T> items, Predicate<T> matches) {
        return IntStream.range(0, items.size())
                .filter(index -> matches.test(items.get(index)))
                .findFirst().orElse(-1);
}

এবং এটিকে কল করুন:

int index = indexOf(myList, item->item.getId()==100);

এবং যদি কোনও সংগ্রহ ব্যবহার করে থাকেন তবে এটি ব্যবহার করে দেখুন।

   public static <T> int indexOf(Collection<T> items, Predicate<T> matches) {
        int index = -1;
        Iterator<T> it = items.iterator();
        while (it.hasNext()) {
            index++;
            if (matches.test(it.next())) {
                return index;
            }
        }
        return -1;
    }

0

একটি সম্ভাব্য উপায় হ'ল প্রতিটি উপাদানকে প্রবাহে সূচি দেওয়া:

AtomicInteger index = new AtomicInteger();
Stream.of(names)
  .map(e->new Object() { String n=e; public i=index.getAndIncrement(); })
  .filter(o->o.n.length()<=o.i) // or do whatever you want with pairs...
  .forEach(o->System.out.println("idx:"+o.i+" nam:"+o.n));

একটি স্ট্রিম বরাবর বেনাম শ্রেণি ব্যবহার করা খুব কার্যকর হওয়ার সময় ভাল ব্যবহৃত হয় না।


0

আপনার map অগত্যা
লিনকু উদাহরণের সবচেয়ে কাছের ল্যাম্বদা দরকার নেই:

int[] idx = new int[] { 0 };
Stream.of( names ).filter( name -> name.length() <= idx[0]++ ).collect( Collectors.toList() );

0
String[] namesArray = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
String completeString
         =  IntStream.range(0,namesArray.length)
           .mapToObj(i -> namesArray[i]) // Converting each array element into Object
           .map(String::valueOf) // Converting object to String again
           .collect(Collectors.joining(",")); // getting a Concat String of all values
        System.out.println(completeString);

আউটপুট: স্যাম, পামেলা, ডেভ, পাস্কাল, এরিক

String[] namesArray = {"Sam","Pamela", "Dave", "Pascal", "Erik"};

IntStream.range(0,namesArray.length)
               .mapToObj(i -> namesArray[i]) // Converting each array element into Object
               .map(String::valueOf) // Converting object to String again
               .forEach(s -> {
                //You can do various operation on each element here
                System.out.println(s);
               }); // getting a Concat String of all 

তালিকাতে সংগ্রহ করতে:

String[] namesArray = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
 List<String> namesList
                =  IntStream.range(0,namesArray.length)
                .mapToObj(i -> namesArray[i]) // Converting each array element into Object
                .map(String::valueOf) // Converting object to String again
                .collect(Collectors.toList()); // collecting elements in List
        System.out.println(listWithIndex);

উপরের প্রশ্নের সমাধানটি Listএকটি উপাদান এলিক সমন্বিত বলে আশা করা হচ্ছে ।
কাপলান

আমি তালিকায় সংগ্রহ করার জন্য একটি উদাহরণও যুক্ত করেছি।
অর্পণ সায়নী

0

যেমন জিন-ব্যাপটিস্ট-ইউনিস বলেছেন, আপনার স্ট্রিমটি যদি জাভা তালিকার উপর ভিত্তি করে থাকে তবে অ্যাটমিকআইন্টিজার এবং এর ইনক্রিমেন্টএন্ডগেট পদ্ধতিটি ব্যবহার করা সমস্যার একটি খুব ভাল সমাধান এবং প্রত্যাবর্তিত পূর্ণসংখ্যার যতক্ষণ না আপনি মূল তালিকার সূচকের সাথে মিলে যায় সমান্তরাল স্ট্রিম ব্যবহার করবেন না।


0

আপনার যদি প্রতিটি সূচকে সূচির প্রয়োজন হয় তবে এটি একটি উপায় সরবরাহ করে।

  public class IndexedValue {

    private final int    index;
    private final Object value;

    public IndexedValue(final int index, final Object value) { 
        this.index = index;
        this.value = value;
    }

    public int getIndex() {
        return index;
    }

    public Object getValue() {
        return value;
    }
}

তারপরে এটি নীচে ব্যবহার করুন।

@Test
public void withIndex() {
    final List<String> list = Arrays.asList("a", "b");
    IntStream.range(0, list.size())
             .mapToObj(index -> new IndexedValue(index, list.get(index)))
             .forEach(indexValue -> {
                 System.out.println(String.format("%d, %s",
                                                  indexValue.getIndex(),
                                                  indexValue.getValue().toString()));
             });
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.