假设我创建了一个像这样的对象类
public class thing {
private String name;
private Integer num;
public oDetails (String a, Integer b) {
name = a;
num = b;
}
...gets/ sets/ etc
现在我想创建一个arraylist来保存一些像这样的对象类。
ArrayList<thing> myList = new ArrayList<thing>;
thing first = new thing("Star Wars", 3);
thing second = new thing("Star Wars", 1);
myList.add(first);
myList.add(second);
我想包含某种逻辑,以便在这种情况下...当我们尝试添加对象“second”而不是向arrayList添加新对象时,我们将second.getNum()添加到first.getNum ()。因此,如果您要遍历ArrayList,那么它将是
"Star Wars", 4
我无法想出一个处理这个问题的优雅方法。随着arraylist的增长,搜索它以确定是否存在重复的名称项变得麻烦。任何人都可以提供一些指导吗?
答案 0 :(得分:4)
如果您想拥有一组唯一对象,请使用Set
代替List
。
此外,如果您想在对象被视为相等时自己定义,请考虑覆盖该类的equals
和hashCode
方法。
答案 1 :(得分:4)
您必须创建自己的方法来检查Thing类的name
字段是否设置为“星球大战”,然后添加到Class Thing的相应num
字段中,是一种可能的解决方案
另一种解决方案是使用名称字段为Map
的密钥,将num字段用作值。
例如:
public class Thing
{
private String name;
private int num;
public Thing(String name, int num)
{
this.name = name;
this.num = num;
}
}
public class ThingMap
{
Map<String, Integer> thingMap;
public ThingMap()
{
this.thingMap = new HashMap<>();
}
public void put(Thing t)
{
String k = t.getName();
Integer v = t.getNum();
if(thingMap.get(k) == null) //no entry exists
{
thingMap.put(k, v);
}
else //entry exists
{
//add to the current value
thingMap.put(k, thingMap.get(k) + v);
}
}
public Integer get(String k)
{
return this.thingMap.get(k);
}
}
public class TestThing
{
public static void main(String[] args)
{
ThingMap tMap = new ThingMap();
Thing a = new Thing("Star Wars", 3);
Thing b = new Thing("Star Wars", 1);
tMap.put(a);
tMap.put(b);
System.out.println("Current value: " + tMap.get(a.getName());
}
}
希望这有帮助。
答案 2 :(得分:1)
恕我直言,如果你不想改变你的班级,使用Map<String, Integer>
而不是ArrayList
或Map<String, Thing>
会更有意义。
答案 3 :(得分:1)
你需要在你的类中覆盖 equals 方法和 hashCode 方法这样:
public class Thing {
private String name;
private Integer num;
public Thing(String a, Integer b) {
name = a;
num = b;
}
public void setName(String name) {
this.name = name;
}
public void setNum(Integer num) {
this.num = num;
}
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
if((obj == null) || (obj.getClass() != this.getClass())){
return false;
}
Thing that = (Thing)obj;
// Use the equality == operator to check if the argument is the reference to this object,
// if yes. return true. This saves time when actual comparison is costly.
return num == that.num &&
(name == that.name || (name != null && name.equals(that.name)));
}
/**
* This method returns the hash code value for the object on which this method is invoked.
* This method returns the hash code value as an integer and is supported for the benefit of
* hashing based collection classes such as Hashtable, HashMap, HashSet etc. This method must
* be overridden in every class that overrides the equals method.
*
* @return
*/
@Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + num;
hash = 31 * hash + (null == name ? 0 : name.hashCode());
return hash;
}
}
然后你可以这样使用它:
ArrayList<Thing> myList = new ArrayList<>();
Thing first = new Thing("Star Wars", 3);
if(!myList.contains(first)){
myList.add(first);
}
Thing second = new Thing("Star Wars", 1);
if(!myList.contains(second)){
myList.add(second);
}
在我的情况下,我使用LinkedHashSet来维护插入顺序,因为我认为会更有效率。我没有尝试使用ArrayList这个例子。
有关详细信息,请参阅此处:why I override equals and hashCode in this way
答案 4 :(得分:0)
如果你想最后使用List而不是写Comparator
,
通过编写Comparator,您可以创建类似set的行为。
答案 5 :(得分:-1)
@Override
protected Void doInBackground(Void... voids) {
HttpHandler sh = new HttpHandler();
String jsonStr = sh.makeServiceCall(Utils.SERVER_URL);
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObject = new JSONObject(jsonStr);
JSONArray result = jsonObject.getJSONArray("result");
for (int i = 0; i < result.length(); i++) {
JSONObject data = result.getJSONObject(i);
String day = data.getString("day");
dataModels.add(day);
LinkedHashSet<String> lhs = new LinkedHashSet<String>();
lhs.addAll(dataModels);
// Removing ArrayList elements
dataModels.clear();
dataModels.addAll(lhs);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}