Java 學習記錄76 — Sorted Collections — 3/4

張小雄
9 min readJul 16, 2021

--

Basket.java 改

package Stock;import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class Basket {
private final String name;
private final Map<StockItem, Integer> list;
public Basket(String name) {
this.name = name;
this.list = new HashMap<>();
}
public int addToBasket(StockItem item, int quantity) {
if ((item != null) && (quantity > 0)) {
int inBasket = list.getOrDefault(item, 0);
list.put(item, inBasket + quantity);
return inBasket;
}
return 0;
}
public Map<StockItem, Integer> Items() {
return Collections.unmodifiableMap(list);
}
@Override
public String toString() {
String s = "\nShopping basket " + name + " contains " + list.size() + (list.size() == 1 ? " item" : " items") + "\n";
double totalCost = 0.0;
for (Map.Entry<StockItem, Integer> item : list.entrySet()) {
s = s + item.getKey() + ". " + item.getValue() + " purchased\n";
totalCost += item.getKey().getPrice() * item.getValue();
}
return s + " Total cost " + totalCost;
}
}

Main.java 改

package Stock;public class Main {
private static StockList stockList = new StockList();
public static void main(String[] args) {
StockItem temp = new StockItem("bread", 0.86, 100);
stockList.addStock(temp);
temp = new StockItem("bread", 0.2, 500);
stockList.addStock(temp);
temp = new StockItem("cake", 1.10, 7);
stockList.addStock(temp);
temp = new StockItem("car", 12.50, 2);
stockList.addStock(temp);
temp = new StockItem("chair", 62.0, 10);
stockList.addStock(temp);
temp = new StockItem("cup", 0.50, 200);
stockList.addStock(temp);
temp = new StockItem("door", 72.95, 4);
stockList.addStock(temp);
temp = new StockItem("juice", 2.50, 36);
stockList.addStock(temp);
temp = new StockItem("phone", 96.99, 35);
stockList.addStock(temp);
temp = new StockItem("towel", 2.40, 80);
stockList.addStock(temp);
temp = new StockItem("vase", 8.76, 40);
stockList.addStock(temp);
// for (String s : stockList.Items().keySet()) {
// System.out.println(s);
// }
Basket zedBasket = new Basket("Zed");
sellItem(zedBasket, "car", 1);
System.out.println(zedBasket);
sellItem(zedBasket, "car", 1);
System.out.println(zedBasket);
sellItem(zedBasket, "car", 1);
sellItem(zedBasket, "something", 1);
System.out.println(zedBasket);
sellItem(zedBasket, "juice", 4);
sellItem(zedBasket, "cup", 12);
sellItem(zedBasket, "bread", 1);
System.out.println(zedBasket);
System.out.println(stockList);
}
public static int sellItem(Basket basket, String item, int quantity) {
// retrieve the item from stock list
StockItem stockItem = stockList.getStockItem(item);
if (stockItem == null) {
System.out.println("We don't sell " + item);
return 0;
}
if (stockItem.quantityInStock() == 0) {
System.out.println(item.toUpperCase() + " already sold out !");
return 0;
}
if (stockList.sellStock(item, quantity) != 0) {
basket.addToBasket(stockItem, quantity);
return quantity;
}
return 0;
}
}

輸出結果:

Shopping basket Zed contains 1 item

car : $12.5. 1 purchased

Total cost 12.5

Shopping basket Zed contains 1 item

car : $12.5. 2 purchased

Total cost 25.0

CAR already sold out !

We don’t sell something

Shopping basket Zed contains 1 item

car : $12.5. 2 purchased

Total cost 25.0

Shopping basket Zed contains 4 items

bread : $0.2. 1 purchased

car : $12.5. 2 purchased

juice : $2.5. 4 purchased

cup : $0.5. 12 purchased

Total cost 41.2

Stock List

bread : $0.2 There are 599 items in stock. Total value of items: 119.80

cake : $1.1 There are 7 items in stock. Total value of items: 7.70

car : $12.5 There are 0 items in stock. Total value of items: 0.00

chair : $62.0 There are 10 items in stock. Total value of items: 620.00

cup : $0.5 There are 188 items in stock. Total value of items: 94.00

door : $72.95 There are 4 items in stock. Total value of items: 291.80

juice : $2.5 There are 32 items in stock. Total value of items: 80.00

phone : $96.99 There are 35 items in stock. Total value of items: 3394.65

towel : $2.4 There are 80 items in stock. Total value of items: 192.00

vase : $8.76 There are 40 items in stock. Total value of items: 350.40

Total stock value 5150.35

改了 Basket 裡面的 toString() 若數量大於 1,item 就改為顯示 items

還有 Main 裡面的 sellItem() 若庫存為 0,提示已無庫存訊息

Basket.java 改

package Stock;import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
public class Basket {
private final String name;
private final Map<StockItem, Integer> list;
public Basket(String name) {
this.name = name;
this.list = new TreeMap<>();
}
public int addToBasket(StockItem item, int quantity) {
if ((item != null) && (quantity > 0)) {
int inBasket = list.getOrDefault(item, 0);
list.put(item, inBasket + quantity);
return inBasket;
}
return 0;
}
public Map<StockItem, Integer> Items() {
return Collections.unmodifiableMap(list);
}
@Override
public String toString() {
String s = "\nShopping basket " + name + " contains " + list.size() + (list.size() == 1 ? " item" : " items") + "\n";
double totalCost = 0.0;
for (Map.Entry<StockItem, Integer> item : list.entrySet()) {
s = s + item.getKey() + ". " + item.getValue() + " purchased\n";
totalCost += item.getKey().getPrice() * item.getValue();
}
return s + " Total cost " + totalCost;
}
}

輸出結果:

Call Stock.StockItem.compareTo()

Shopping basket Zed contains 1 item

car : $12.5. 1 purchased

Total cost 12.5

Call Stock.StockItem.compareTo()

Call Stock.StockItem.compareTo()

Shopping basket Zed contains 1 item

car : $12.5. 2 purchased

Total cost 25.0

CAR already sold out !

We don’t sell something

Shopping basket Zed contains 1 item

car : $12.5. 2 purchased

Total cost 25.0

Call Stock.StockItem.compareTo()

Call Stock.StockItem.compareTo()

Call Stock.StockItem.compareTo()

Call Stock.StockItem.compareTo()

Call Stock.StockItem.compareTo()

Call Stock.StockItem.compareTo()

Call Stock.StockItem.compareTo()

Call Stock.StockItem.compareTo()

Call Stock.StockItem.compareTo()

Call Stock.StockItem.compareTo()

Call Stock.StockItem.compareTo()

Call Stock.StockItem.compareTo()

Call Stock.StockItem.compareTo()

Call Stock.StockItem.compareTo()

Call Stock.StockItem.compareTo()

Shopping basket Zed contains 4 items

bread : $0.2. 1 purchased

car : $12.5. 2 purchased

cup : $0.5. 12 purchased

juice : $2.5. 4 purchased

Total cost 41.2

Stock List

bread : $0.2 There are 599 items in stock. Total value of items: 119.80

cake : $1.1 There are 7 items in stock. Total value of items: 7.70

car : $12.5 There are 0 items in stock. Total value of items: 0.00

chair : $62.0 There are 10 items in stock. Total value of items: 620.00

cup : $0.5 There are 188 items in stock. Total value of items: 94.00

door : $72.95 There are 4 items in stock. Total value of items: 291.80

juice : $2.5 There are 32 items in stock. Total value of items: 80.00

phone : $96.99 There are 35 items in stock. Total value of items: 3394.65

towel : $2.4 There are 80 items in stock. Total value of items: 192.00

vase : $8.76 There are 40 items in stock. Total value of items: 350.40

Total stock value 5150.35

若要讓購物清單按字母排序的話

把原本的 Ha改成 TreeMap

StockItem.java 改

StockList.java 改

Basket.java 改

Main.java 改

package Stock;public class Main {
private static StockList stockList = new StockList();
public static void main(String[] args) {
StockItem temp = new StockItem("bread", 0.86, 100);
stockList.addStock(temp);
temp = new StockItem("bread", 0.2, 500);
stockList.addStock(temp);
temp = new StockItem("cake", 1.10, 7);
stockList.addStock(temp);
temp = new StockItem("car", 12.50, 2);
stockList.addStock(temp);
temp = new StockItem("chair", 62.0, 10);
stockList.addStock(temp);
temp = new StockItem("cup", 0.50, 200);
stockList.addStock(temp);
temp = new StockItem("door", 72.95, 4);
stockList.addStock(temp);
temp = new StockItem("juice", 2.50, 36);
stockList.addStock(temp);
temp = new StockItem("phone", 96.99, 35);
stockList.addStock(temp);
temp = new StockItem("towel", 2.40, 80);
stockList.addStock(temp);
temp = new StockItem("vase", 8.76, 40);
stockList.addStock(temp);
// for (String s : stockList.Items().keySet()) {
// System.out.println(s);
// }
// Basket zedBasket = new Basket("Zed");
// sellItem(zedBasket, "car", 1);
// System.out.println(zedBasket);
//
// sellItem(zedBasket, "car", 1);
// System.out.println(zedBasket);
//
//
// sellItem(zedBasket, "car", 1);
// sellItem(zedBasket, "something", 1);
// System.out.println(zedBasket);
//
// sellItem(zedBasket, "juice", 4);
// sellItem(zedBasket, "cup", 12);
// sellItem(zedBasket, "bread", 1);
// System.out.println(zedBasket);
//
// System.out.println(stockList);
temp = new StockItem("pen", 1.5);
stockList.Items().put(temp.getName(), temp);
} public static int sellItem(Basket basket, String item, int quantity) {
// retrieve the item from stock list
StockItem stockItem = stockList.getStockItem(item);
if (stockItem == null) {
System.out.println("We don't sell " + item);
return 0;
}
if (stockItem.quantityInStock() == 0) {
System.out.println(item.toUpperCase() + " already sold out !");
return 0;
}
if (stockList.sellStock(item, quantity) != 0) {
basket.addToBasket(stockItem, quantity);
return quantity;
}
return 0;
}
}

輸出結果:

Exception in thread “main” java.lang.UnsupportedOperationException

at java.base/java.util.Collections$UnmodifiableMap.put(Collections.java:1457)

at Stock.Main.main(Main.java:65)

會報錯就是因為下面這段

public Map<StockItem, Integer> Items() {
return Collections.unmodifiableMap(list);
}

這串就是防止用其他方式加入 Map 裡,只能用我們提供的方式

Main.java 改

package Stock;public class Main {
private static StockList stockList = new StockList();
public static void main(String[] args) {
StockItem temp = new StockItem("bread", 0.86, 100);
stockList.addStock(temp);
temp = new StockItem("bread", 0.2, 500);
stockList.addStock(temp);
temp = new StockItem("cake", 1.10, 7);
stockList.addStock(temp);
temp = new StockItem("car", 12.50, 2);
stockList.addStock(temp);
temp = new StockItem("chair", 62.0, 10);
stockList.addStock(temp);
temp = new StockItem("cup", 0.50, 200);
stockList.addStock(temp);
temp = new StockItem("door", 72.95, 4);
stockList.addStock(temp);
temp = new StockItem("juice", 2.50, 36);
stockList.addStock(temp);
temp = new StockItem("phone", 96.99, 35);
stockList.addStock(temp);
temp = new StockItem("towel", 2.40, 80);
stockList.addStock(temp);
temp = new StockItem("vase", 8.76, 40);
stockList.addStock(temp);
// for (String s : stockList.Items().keySet()) {
// System.out.println(s);
// }
// Basket zedBasket = new Basket("Zed");
// sellItem(zedBasket, "car", 1);
// System.out.println(zedBasket);
//
// sellItem(zedBasket, "car", 1);
// System.out.println(zedBasket);
//
//
// sellItem(zedBasket, "car", 1);
// sellItem(zedBasket, "something", 1);
// System.out.println(zedBasket);
//
// sellItem(zedBasket, "juice", 4);
// sellItem(zedBasket, "cup", 12);
// sellItem(zedBasket, "bread", 1);
// System.out.println(zedBasket);
//
// temp = new StockItem("pen", 1.5);
// stockList.Items().put(temp.getName(), temp);
stockList.Items().get("car").adjustStock(2000);
stockList.getStockItem("car").adjustStock(-1000);
System.out.println(stockList);
} public static int sellItem(Basket basket, String item, int quantity) {
// retrieve the item from stock list
StockItem stockItem = stockList.getStockItem(item);
if (stockItem == null) {
System.out.println("We don't sell " + item);
return 0;
}
if (stockItem.quantityInStock() == 0) {
System.out.println(item.toUpperCase() + " already sold out !");
return 0;
}
if (stockList.sellStock(item, quantity) != 0) {
basket.addToBasket(stockItem, quantity);
return quantity;
}
return 0;
}
}

輸出結果:

Stock List

bread : $0.2 There are 600 items in stock. Total value of items: 120.00

cake : $1.1 There are 7 items in stock. Total value of items: 7.70

car : $12.5 There are 1002 items in stock. Total value of items: 12525.00

chair : $62.0 There are 10 items in stock. Total value of items: 620.00

cup : $0.5 There are 200 items in stock. Total value of items: 100.00

door : $72.95 There are 4 items in stock. Total value of items: 291.80

juice : $2.5 There are 36 items in stock. Total value of items: 90.00

phone : $96.99 There are 35 items in stock. Total value of items: 3394.65

towel : $2.4 There are 80 items in stock. Total value of items: 192.00

vase : $8.76 There are 40 items in stock. Total value of items: 350.40

Total stock value 17691.55

要注意的是 Map 本身無法透過其他方式修改,而不是 Map 裡面的 Object 無法被修改

這邊展示兩種其他方法修改庫存商品的數量

StockList.java 改

package Stock;import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
public class StockList {
private final Map<String, StockItem> list;
public StockList() {
this.list = new LinkedHashMap<>();
}
public int addStock(StockItem stockItem) {
if (stockItem != null) {
// check if already have stockItem, jf get null just pass stockItem of parameter
StockItem inStock = list.getOrDefault(stockItem.getName(), stockItem);
// if there are already stocks on this item, adjust the quantity
if (inStock != stockItem) {
stockItem.adjustStock(inStock.quantityInStock());
}
list.put(stockItem.getName(), stockItem);
return stockItem.quantityInStock();
}
return 0;
}
public int sellStock(String item, int quantity) {
StockItem inStock = list.getOrDefault(item, null);
if ((inStock != null) && (inStock.quantityInStock() >= quantity) && (quantity > 0)) {
inStock.adjustStock(-quantity);
return quantity;
}
return 0;
}
public StockItem getStockItem(String key) {
return list.get(key);
}
public Map<String, StockItem> Items() {
return Collections.unmodifiableMap(list);
}
public Map<String, Double> PriceList() {
Map<String, Double> prices = new LinkedHashMap<>();
for (Map.Entry<String, StockItem> item : list.entrySet()) {
prices.put(item.getKey(), item.getValue().getPrice());
}
return Collections.unmodifiableMap(prices);
}
@Override
public String toString() {
String s = "\nStock List\n";
double totalCost = 0.0;
for (Map.Entry<String, StockItem> item : list.entrySet()) {
StockItem stockItem = item.getValue();
double itemValue = stockItem.getPrice() * stockItem.quantityInStock(); s = s + stockItem + " There are " + stockItem.quantityInStock() + " items in stock. Total value of items: ";
s = s + String.format("%.2f", itemValue) + "\n";
totalCost += itemValue;
}
return s + " Total stock value " + String.format("%.2f", totalCost);
}
}

Main.java 改

package Stock;import java.util.Map;public class Main {
private static StockList stockList = new StockList();
public static void main(String[] args) {
StockItem temp = new StockItem("bread", 0.86, 100);
stockList.addStock(temp);
temp = new StockItem("bread", 0.2, 500);
stockList.addStock(temp);
temp = new StockItem("cake", 1.10, 7);
stockList.addStock(temp);
temp = new StockItem("car", 12.50, 2);
stockList.addStock(temp);
temp = new StockItem("chair", 62.0, 10);
stockList.addStock(temp);
temp = new StockItem("cup", 0.50, 200);
stockList.addStock(temp);
temp = new StockItem("door", 72.95, 4);
stockList.addStock(temp);
temp = new StockItem("juice", 2.50, 36);
stockList.addStock(temp);
temp = new StockItem("phone", 96.99, 35);
stockList.addStock(temp);
temp = new StockItem("towel", 2.40, 80);
stockList.addStock(temp);
temp = new StockItem("vase", 8.76, 40);
stockList.addStock(temp);
// for (String s : stockList.Items().keySet()) {
// System.out.println(s);
// }
// Basket zedBasket = new Basket("Zed");
// sellItem(zedBasket, "car", 1);
// System.out.println(zedBasket);
//
// sellItem(zedBasket, "car", 1);
// System.out.println(zedBasket);
//
//
// sellItem(zedBasket, "car", 1);
// sellItem(zedBasket, "something", 1);
// System.out.println(zedBasket);
//
// sellItem(zedBasket, "juice", 4);
// sellItem(zedBasket, "cup", 12);
// sellItem(zedBasket, "bread", 1);
// System.out.println(zedBasket);
//
// temp = new StockItem("pen", 1.5);
// stockList.Items().put(temp.getName(), temp);
// stockList.Items().get("car").adjustStock(2000);
// stockList.getStockItem("car").adjustStock(-1000);
// System.out.println(stockList);
for (Map.Entry<String, Double> price : stockList.PriceList().entrySet()) {
System.out.println(price.getKey() + " costs: $" + price.getValue());
}
} public static int sellItem(Basket basket, String item, int quantity) {
// retrieve the item from stock list
StockItem stockItem = stockList.getStockItem(item);
if (stockItem == null) {
System.out.println("We don't sell " + item);
return 0;
}
if (stockItem.quantityInStock() == 0) {
System.out.println(item.toUpperCase() + " already sold out !");
return 0;
}
if (stockList.sellStock(item, quantity) != 0) {
basket.addToBasket(stockItem, quantity);
return quantity;
}
return 0;
}
}

輸出結果:

bread costs: $0.2

cake costs: $1.1

car costs: $12.5

chair costs: $62.0

cup costs: $0.5

door costs: $72.95

juice costs: $2.5

phone costs: $96.99

towel costs: $2.4

vase costs: $8.76

新增一個功能,顯示庫存的商品價格

本篇使用代碼

--

--

張小雄
張小雄

Written by 張小雄

記錄成為軟體工程師的過程

No responses yet