java list 查找元素

從list中查找符合條件的元素是一個很常見的需求,有很多辦法可以做到,詳見參考鏈接。本文討論的點是如何把這個過程封裝成一個方法,這樣做的好處如下:

1.簡化調用

2.容易替換成不同的實現

3.可以做一些統一的處理

這就是抽象的好處吧

假設List中保存的元素是Item,定義如下:

public class Item {
	private Integer id;
	private Integer weight;
 
	public Item(Integer id, Integer weight) {
		this.id = id;
		this.weight = weight;
	}
 
	public Integer getId() {
		return id;
	}
 
	public void setId(Integer id) {
		this.id = id;
	}
 
	public Integer getWeight() {
		return weight;
	}
 
	public void setWeight(Integer weight) {
		this.weight = weight;
	}
}

抽象後的方法如下:

public static <T extends Object>
T getElem(List<T> objs, Integer id, Class<?> clazz) {
	try {
		Method getIdFunc = clazz.getMethod("getId");
		for (T obj : objs) {
			Integer rId = (Integer)getIdFunc.invoke(obj);
			if (rId.equals(id)) {
				return obj;
			}
		}

	} catch (Exception e) {
		LogUtil.LOG_BASE.error("getElem異常",  e.getMessage(),  e);
	}

	return null;
}

調用起來如下:

public Item getItemById(int id) {
    return Util.getEle(items, 1, Item.class);
}

// 測試代碼
List<Item> items = new ArrayList<>();
 
items.add(new Item(1, 50));
items.add(new Item(2, 50));
items.add(new Item(3, 50));

Item item = getItemById(items);

是挺簡潔的,但是這麼做的缺點是這裏使用了反射,反射的問題在於效率,對於調用不太頻繁的方法還好,但是對於這種過於頻繁的方法,顯然就不是很合適了,因此繼續思考,有了如下方法。

方法二是基於java 8 Stream API實現,沒有抽象前,查找代碼如下:

Customer james = customers.stream()
  .filter(customer -> "James".equals(customer.getName()))
  .findAny()
  .orElse(null);

抽象以後,有了如下方法:

public static <T extends Object>
T getEle(List<T> objs, Predicate<T> predicate) {
	return objs.stream()
			.filter(predicate)
			.findAny()
			.orElse(null);
}

這樣查找調用就變成了

public Item getItemById(int id) {
    return Util.getEle(items, item -> item.getId() == id);
}

List<Item> items = new ArrayList<>();
 
items.add(new Item(1, 50));
items.add(new Item(2, 50));
items.add(new Item(3, 50));

Item item = Util.getEle(items, item -> item.getId() == id);

這樣做,測試了一下,效率提升了好幾倍

 

參考:

https://www.baeldung.com/find-list-element-java

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章