java arraylist 不重复_关于java:防止arraylist中的重复条目

假设我像这样创建一些对象类

public class thing {

private String name;

private Integer num;

public oDetails (String a, Integer b) {

name = a;

num = b;

}

...gets/ sets/ etc

现在我想创建一个arraylist来保存这样的对象类。

ArrayList myList = new ArrayList;

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的增长,搜索它以确定是否存在重复的名称项变得麻烦。 任何人都可以提供一些指导吗?

看起来你想要使用java.util.Map。

我认为最好的方法是实现"无重复"数组列表。 请参阅我的回答:stackoverflow.com/a/35788695/130028

您必须创建自己的方法来检查是否将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 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());

}

}

希望这可以帮助。

将地图放在Thing类中没有意义

@LuiggiMendoza这只是一个例子。 op可以将名称放在他们想要的任何地方。

如果Thing是一个模型类,为什么要放一个只存储实际对象数据的容器?

@LuiggiMendoza嗯,是的,我想这真的没有意义,每件事都有自己的地图。

你应该编辑你的答案,并使用另一个有容器的类。这是Map用法的不良样本

@LuiggiMendoza更好?

是的,它显示了Map接口的正确用法。

如果要拥有一组唯一对象,请使用Set而不是List。

此外,如果要在对象被视为相等时自己定义,请考虑覆盖类的equals和hashCode方法。

对于equal()函数的一般语义,这是不合理的。

new Thing("Star Wars", 3)和new Thing("Star Wars", 1)是两个不同的对象。

我赞同猎人的评论,如果你创造了一套类型的东西然后不会"星球大战",3和"星球大战",1被视为独特的对象?

您可以覆盖equals()方法以强制它像这样工作,但正如Vincent提到的那样违反了equals()的一般契约。

你需要以这种方式覆盖类中的equals方法和hashCode方法Thing:

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 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这个例子。

有关更多信息,请参阅此处:为什么我以这种方式覆盖equals和hashCode

恕我直言,如果你不想改变你的类,使用Map代替ArrayList更有意义,或者使用Map。

如果你想最后使用List而不是写你的Comparator,

通过编写Comparator,您可以创建类似set的行为。

比较器如何解决他的问题,当ArrayList#add只是在内部数组的末尾插入元素?

@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 lhs = new LinkedHashSet();

lhs.addAll(dataModels);

// Removing ArrayList elements

dataModels.clear();

dataModels.addAll(lhs);

}

} catch (Exception e) {

e.printStackTrace();

}

}

return null;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值