0

I am having an items class and a tester class for ordering the items and setting price. Am using two methods with stream passed as parameter to the methods. But getting error stream has already been operated upon or closed while executing.

Item Class:

public class Item {
int itemId;
String itemName;
ItemType itemType;
float weightInGrams;
float price;

public Item(int itemId, String itemName, ItemType itemType, float weightInGrams, float price) {
    this.itemId = itemId;
    this.itemName = itemName;
    this.itemType = itemType;
    this.weightInGrams = weightInGrams;
    this.price = price;
}

public int getItemId() {
    return itemId;
}

public void setItemId(int itemId) {
    this.itemId = itemId;
}

public String getItemName() {
    return itemName;
}

public void setItemName(String itemName) {
    this.itemName = itemName;
}

public ItemType getItemType() {
    return itemType;
}

public void setItemType(ItemType itemType) {
    this.itemType = itemType;
}

public float getWeightInGrams() {
    return weightInGrams;
}

public void setWeightInGrams(float weightInGrams) {
    this.weightInGrams = weightInGrams;
}

public float getPrice() {
    return price;
}

public void setPrice(float price) {
    this.price = price;
}

public static void filterItemsWeight(Stream<Item> items) {
    items.map(t-> t.getWeightInGrams())
        .sorted(Comparator.reverseOrder())
        .forEach(item-> System.out.println(item));
}
@Override
public String toString() {
    return "Item ID: "+this.getItemId()+" , Item Name : "+this.itemName+" , Item Type : "+this.itemType+
            " , Weight in grams : "+this.getWeightInGrams()+" , Price : "+this.getPrice();
}

public static void calculatePricePerItem(Stream<Item> itemsList) {
    Supplier<Stream<Item>> streamSupplier = ()-> itemsList;
    streamSupplier.get().filter(t-> t.getItemType().equals(ItemType.GOLD))
    .forEach(item->item.setPrice(item.getWeightInGrams()*2700));
    itemsList.forEach(t-> System.out.println(t));
    itemsList.filter(t-> t.getItemType().equals(ItemType.SILVER))
    .forEach(item->item.setPrice(item.getWeightInGrams()*34));
    itemsList.forEach(t-> System.out.println(t));

}

Tester Class

public class Tester {
public static void main(String[] args) {
    Item it1 = new Item(10, "Ring", ItemType.GOLD, 23.3f, 40656.5f);
    Item it2 = new Item(11, "Necklace", ItemType.GOLD, 45.3f, 140656.5f);
    Item it3 = new Item(12, "Ring", ItemType.SILVER, 25.3f, 956.5f);
    Item it4 = new Item(13, "Coin", ItemType.GOLD, 20.3f, 37656.5f);
    Item it5 = new Item(14, "Bangle", ItemType.GOLD, 40f, 124200.5f);
    Item it6 = new Item(15, "Bangle", ItemType.GOLD, 45.3f, 140656.5f);
    List<Item> itemList = new ArrayList<>();
    itemList.add(it1);
    itemList.add(it2);
    itemList.add(it3);
    itemList.add(it4);
    itemList.add(it5);
    itemList.add(it6);
    Supplier<Stream<Item>> streamSupplier = ()-> itemList.stream();
    Item.filterItemsWeight(streamSupplier.get());
    Item.calculatePricePerItem(streamSupplier.get());

}

I have tried using supplier stream but still getting the same error for method calculatePricePerItem. Could you please help in resolving this?

Stefan Zobel
  • 3,182
  • 7
  • 28
  • 38
Dinu
  • 845
  • 3
  • 13
  • 27

1 Answers1

0

After that

Supplier<Stream<Item>> streamSupplier = ()-> itemsList;
    streamSupplier.get().filter(t-> t.getItemType().equals(ItemType.GOLD))
    .forEach(item->item.setPrice(item.getWeightInGrams()*2700));

The stream is closed.

So the following line itemsList.forEach(t->System.out.println(t)

calls the foreach terminal operation on a already closed stream . It is forbidden.

CodeScale
  • 3,046
  • 1
  • 12
  • 20
  • so if the stream is closed then how can i print the items from that stream? – Dinu May 05 '20 at 05:18
  • 1
    you can't consume it anymore (even it is just for display something). So no more function can be called on a closed stream. A stream is closed when a terminal operation is called on it. Like `forEach`, `count`, `collect`.... – CodeScale May 05 '20 at 05:44