从数组列表中删除重复项

Posted

技术标签:

【中文标题】从数组列表中删除重复项【英文标题】:deleting duplicates from array list 【发布时间】:2022-01-20 15:06:44 【问题描述】:

我正在创建一个简单的 RPG 主机游戏,我正处于创建库存和战利品系统的阶段。在程序中,class Playerclass Monster都有arrayList Backpack属性,当程序创建怪物类的对象时,怪物背包里的物品也会自动创建,杀死怪物后可以拿走到你的背包,这就是我的问题开始的地方,如何优雅地防止背包中的物品重复,@ 987654324@,现在这个功能通过一个一个地检查每个项目的嵌套循环来查看它是否已经在背包中如果不是再次添加它,它会增加它的数量属性,如果我的背包中没有这个项目,它只是添加到列表中,解决方案有效,但绝对不是正确的解决方案,因为许多项目这种检查机制会增长很多,如果有人有任何宝贵的提示,我将不胜感激。 我还有第二个想法是创建一个boolean Is_it_in_Backpack 变量,并以某种方式将其与战利品收集机制联系起来

下面是一些代码示例

public class Player  
public static ArrayList<Item> Backpack = new ArrayList<>()

还有Skieleton类:

public class Skieleton extends Monsters 

  public static ArrayList<Item> Backpack;

  public Skieleton() 
       Backpack = new ArrayList<>();
       Backpack.add(new Weapon("Rusty sword", "Just a rusty sword", 3, 2 ));
       Backpack.add(new Armor("Leather Armor", "Old leather armor", 6, 3));
    

类项目:

public class Item 

    public String ItemName;
    public String Description;
    public int ItemSize;
    public int ItemWeight;
    public int Amount;

    public Item(String ItemName, String Description, int ItemSize, int ItemWeight)
    
        this.ItemName = ItemName;
        this.Description = Description;
        this.ItemSize = ItemSize;
        this.ItemWeight = ItemWeight;
    

    public Item() 
    

【问题讨论】:

嗯,你能给我一些简单的例子吗? 我收回我说的话。 Set 不会帮助您合并项目。它将取代它们 正如其中一个答案所说,您可以使用地图。最好把amount从Item中取出,只保留在地图中Map&lt;Item, Integer&gt; @user7 怪物和玩家有关系吗?怪物算玩家吗?由于怪物和玩家都携带背包并且具有相似的属性,因此您可能希望将两者扩展为一个通用类。 【参考方案1】:

我建议你使用扩展 java.util.Set 的类:

如果订单对您不重要,您可以使用HashSet; 如果插入顺序很重要,可以使用LinkedHashSet; 如果自然顺序很重要(按名称或其他属性按字母顺序排列),您可以使用TreeSet 并将接口Comparable 实现到插入到集合中的类上。

但是,无论您的选择如何,建议您实现hashCode()(用于优化)和equals()(让集合识别哪个项目等于其他项目并避免重复)。

【讨论】:

OP 不想替换这些项目。如果存在相同的项目,则必须增加其数量/金额【参考方案2】:

我会使用地图。

这是我的建议:

 import java.util.*;

 class Player  
    public Backpack backpack= new Backpack();


class Monster  

 class Skieleton extends Monster 

  public Backpack backpack= new Backpack();

  public Skieleton() 
       
       backpack.add(new Weapon("Rusty sword", "Just a rusty sword", 3, 2 ));
       backpack.add(new Armor("Leather Armor", "Old leather armor", 6, 3));
    


class Backpack 
    private HashMap<Item,Item> items = new HashMap<>();
    
    public Item add(Item item)
        if (items.containsKey(item))
            items.get(item).Amount=+ item.Amount;
            return items.get(item);
         else 
            items.put(item,item);
            return item;
        
    
    
    public Item get(Item item)
        return items.getOrDefault(item, null);
    

class Item 

    public String ItemName;
    public String Description;
    public int ItemSize;
    public int ItemWeight;
    public int Amount;

    public Item(String ItemName, String Description, int ItemSize, int ItemWeight)
    
        this.ItemName = ItemName;
        this.Description = Description;
        this.ItemSize = ItemSize;
        this.ItemWeight = ItemWeight;
    

    public Item() 
    
    
    public boolean equals(Object o)
        if (o instanceof Item)
            return ItemName.equals( ((Item)o).ItemName);
        
        return false;
    

【讨论】:

你好你能帮我多一点吗?我从来没有处理过hashmaps,反正我也做不到…… 好的。我可以建议一个不使用哈希图的解决方案。它只是数组列表。 它可以是一个 HashMap,我想学习它,但我不理解 100% 的解决方案:D 为什么 HashMap 是 ,而不是例如 ,我是 Java 新手,这是我的第一个项目,只是在这里“看不到”解决方案.... sryy =D 原因是因为Amount在Item对象中。如果它是分开的,那么你可以有 。我将修改我的答案以反映这一点。 我认为我们应该坚持使用 ArrayList。我认为引入 hashmap 只会使事情复杂化。您需要在许多项目类中覆盖 hashCode、equals 等方法。【参考方案3】:

您可以使用 HashMap 来存储项目。首先,我想将 Item 类更改为没有 amount 字段。让一个项目表示一个项目是什么(名称、描述、尺寸和重量)。

这是更新后的背包:

Map<Item, Integer> backpack = new HashMap<>();

要添加项目,您可以使用Map#merge 方法。

public void addItemToBackpack(Item item, int quantity) 
    backpack.merge(item, quantity, (oldQuantity, newQuantity) -> oldQuantity + newQuantity);

我们插入项目及其数量。如果该项目尚不存在,它将使用传递的数量插入。

如果它已经存在,那么将使用现有值 (oldQuantity) 和我们尝试插入的新值 (newQuantity) 调用映射函数 BiFunction。我们将它们相加,返回它,并且项目的值(数量)将使用此值更新。

使用方法引用,我们可以把上面写成,

backpack.merge(item, quantity, Integer::sum);

【讨论】:

你能帮我一些忙吗?我从来没有处理过哈希图,我还有几个问题【参考方案4】:

如果您可以使用第三方库,我建议您使用来自Eclipse Collections 的Bag

随着您的 Item 类在 ItemName 字段上实现 equalshashCode,您的示例用法可能如下所示:


final MutableBag<Item> backPack = new HashBag<>();

final Item rustySword = new Item("Rusty sword", "Just a rusty sword", 3, 2);
final Item leatherArmour = new Item("Leather Armor", "Old leather armor", 6, 3);
     
backPack.add(rustySword);
backPack.add(leatherArmour);
backPack.add(rustySword);

System.out.println(backPack.toMapOfItemToCount());     // prints Item[ItemName='Rusty sword']=2, Item[ItemName='Leather Armor']=1
System.out.println(backPack.occurrencesOf(rustySword));  // prints 2

API 很丰富,并且提供了更多: https://www.eclipse.org/collections/javadoc/11.0.0/org/eclipse/collections/api/bag/Bag.html

【讨论】:

以上是关于从数组列表中删除重复项的主要内容,如果未能解决你的问题,请参考以下文章

jQuery - 从字符串数组中删除重复项[重复]

从2D列表中删除重复项(浮点)

从列表中删除重复项?

删除 int 数组列表中的重复项

从 Python 列表中删除重复项

如何使用列表理解从列表中删除重复项? [复制]