मेरे पास नीचे की तरह वस्तुओं की एक सूची है

public class Price{

    private long id;

    private String productid;

    private long sequence;

    private BigDecimal price;
    
}

मेरे पास नीचे की तरह वस्तुओं की सूची होगी

Price1 -> {1, "p1", 1, 1.0}
Price2 -> {2, "p1", 2, 2.0}
Price3 -> {3, "p1", 3, 3.0}
Price4 -> {4, "p2", 1, 1.0}

प्रत्येक उत्पाद आईडी में कीमतों की एकाधिक प्रविष्टियां हो सकती हैं (क्रमानुसार क्रमित)। नवीनतम मूल्य नवीनतम अनुक्रम के साथ आता है। उपरोक्त डेटा में, उत्पाद p1 की कीमत 3 है, p2 की कीमत 1 है।

मुझे केवल 2 प्रविष्टियां (आईडी 3 और 4) प्राप्त करने के लिए जावा ऑब्जेक्ट्स की उपरोक्त सूची को फ़िल्टर करने की आवश्यकता है। आउटपुट नीचे दी गई सूची के साथ आना चाहिए

Price3 -> {3, "p1", 3, 3.0}
Price4 -> {4, "p2", 1, 1.0}

Java8 स्ट्रीम के साथ कोई मदद?

0
user2555212 5 सितंबर 2021, 11:27

5 जवाब

सबसे बढ़िया उत्तर

यहां आपको वांछित आउटपुट प्राप्त करने के लिए filter के बजाय groupingBy का उपयोग करने की आवश्यकता है। कृपया नीचे उदाहरण देखें:

public class Main {
    public static void main(String[] args) {
        List<Price> data = Arrays.asList(
                new Price(1, "p1", 1, new BigDecimal(1.0)),
                new Price(2, "p1", 2, new BigDecimal(2.0)),
                new Price(3, "p1", 3, new BigDecimal(3.0)),
                new Price(4, "p2", 1, new BigDecimal(1.0)));

        Map<String, Object> result = data.stream().collect(Collectors.groupingBy(Price::getProductid,
                Collectors.collectingAndThen(
                        Collectors.reducing((Price p1, Price p2) -> p1.getSequence() > p2.getSequence() ? p1 : p2),
                        Optional::get)));

        System.out.println(result.values());
    }
}

आउटपुट:

[Price(id=3, productid=p1, sequence=3, price=3), Price(id=4, productid=p2, sequence=1, price=1)]

Price वर्ग:

@AllArgsConstructor
@Data
public class Price {
    private long id;
    private String productid;
    private long sequence;
    private BigDecimal price;
}
1
pcsutar 5 सितंबर 2021, 08:47

प्रति उत्पाद कीमतों को समूहबद्ध करने के लिए Collectors.groupingBy का उपयोग करें और फिर सूची से नवीनतम मूल्य प्राप्त करने के लिए Collectors.maxBy का उपयोग करें। परिणाम प्रति उत्पाद नवीनतम मूल्य वाला नक्शा है।

Map<String, Price> lastPricePerProduct = data.stream().collect(Collectors.groupingBy(Price::getProductid,
            Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparing(Price::getSequence)), Optional::get)));

Collectors.toMap और BinaryOperator.maxBy के साथ अधिक सुरुचिपूर्ण समाधान:

Map<String, Price> lastPricePerProduct = data.stream().collect(Collectors.toMap(Price::getProductid, Function.identity(),
                BinaryOperator.maxBy(Comparator.comparing(Price::getSequence))));
2
katiforis 5 सितंबर 2021, 09:23

आप ऐसा कुछ कर सकते हैं:

prices.stream().collect(Collectors.groupingBy(Price::getProductid)).entrySet().forEach(e -> e.getValue().stream().max(Comparator.comparing(Price::getSequence)).get());

नोट: मैंने उपरोक्त कोड का परीक्षण नहीं किया है, इसलिए इसमें कुछ गलत शब्दार्थ हो सकते हैं।

स्पष्टीकरण:

  1. उत्पाद के अनुसार मानचित्र में संबंधित मूल्य वस्तुओं को एकत्रित करें। Collectors.groupingBy(Price::getProductid)
  2. प्रत्येक कुंजी की कीमतों की सूची के माध्यम से स्ट्रीम करें। entrySet().forEach()
  3. प्रत्येक कुंजी और वापसी वस्तु के लिए अधिकतम अनुक्रम खोजें। max(Comparator.comparing(Price::getSequence)).get()

मुझे बताएं कि क्या आपको और सहायता की आवश्यकता है।

1
Dharman 5 सितंबर 2021, 08:54

जैसा कि java.util.stream.Stream#predicate "एक गैर-हस्तक्षेप, स्टेटलेस विधेय" स्वीकार करता है,
मुझे लगता है कि इसके लिए आपको Collection का उपयोग करना चाहिए।

मैं java.util.stream.Stream#collect एक Collector के साथ।
java. util.stream.Collectors इसे सुविधाजनक बनाता है।

0
hu-zza 5 सितंबर 2021, 08:43

आप इसे आजमा सकते हैं:

 List<Price> list = new ArrayList<>();
    Price p1 = new Price(1,"p1",1,new BigDecimal(1.0));
    Price p2 = new Price(2,"p1",2,new BigDecimal(2.0));
    Price p3 = new Price(3,"p1",3,new BigDecimal(3.0));
    Price p4 = new Price(4,"p3",1,new BigDecimal(1.0));
    list.add(p1);
    list.add(p2);
    list.add(p3);
    list.add(p4);
    List<Price> priceList = list.stream().sorted(Comparator.comparing(Price::getSequence).reversed())
            .filter(distinctByKey(Price::getProductid))
            .collect(Collectors.toList());
    System.out.print(priceList);

public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor)
{
    Map<Object, Boolean> map = new ConcurrentHashMap<>();
    return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

आउटपुट: [Price{id=3, productid='p1', sequence=3, price=3}, Price{id=4, productid='p3', sequence=1, price=1}]

0
Hunny Chawla 5 सितंबर 2021, 09:14