Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否需要Hashmap或ArrayList来迭代和随机访问元素?_Java_Arraylist_Hashmap - Fatal编程技术网

Java 是否需要Hashmap或ArrayList来迭代和随机访问元素?

Java 是否需要Hashmap或ArrayList来迭代和随机访问元素?,java,arraylist,hashmap,Java,Arraylist,Hashmap,我有很多商店: public class Shop { private final String shopName; private boolean shopProperty1; private boolean shopProperty2; } 现在,有时我需要按店铺名称检索店铺,有时我需要对所有现有店铺执行操作 使用ArrayList List<Shop> shops = new ArrayList<>(); Shop shop1 = new

我有很多商店:

public class Shop {
    private final String shopName;
    private boolean shopProperty1;
    private boolean shopProperty2;
}
现在,有时我需要按店铺名称检索店铺,有时我需要对所有现有店铺执行操作

使用ArrayList

List<Shop> shops = new ArrayList<>();
Shop shop1 = new Shop("Megastore", false, true);
Shop shop2 = new Shop("PC-shop", true, true);
Shop shop3 = new Shop("Jim's junkyard", false, false);
shops.add(shop1);
shops.add(shop2);
shops.add(shop3);
按店名检索Megastore:

Shop retrieved;
for (Shop shop : shops) {
    if ("Megastore".equals(shop.getShopName())) {
        retrieved = shop;
        break;
    }
}
Shop retrieved = shops.get("Megastore");
我对使用这种方法的担忧:

使用ArrayList和HashMap按名称检索似乎相当慢,在那里会更好

使用HashMap

Map<String, Shop> shops = new HashMap<>();
Shop shop1 = new Shop("Megastore", false, true);
Shop shop2 = new Shop("PC-shop", true, true);
Shop shop3 = new Shop("Jim's junkyard", false, false);
shops.put(shop1.getShopName(), shop1);
shops.put(shop2.getShopName(), shop2);
shops.put(shop3.getShopName(), shop3);
按店名检索Megastore:

Shop retrieved;
for (Shop shop : shops) {
    if ("Megastore".equals(shop.getShopName())) {
        retrieved = shop;
        break;
    }
}
Shop retrieved = shops.get("Megastore");
我对使用这种方法的担忧:

当shopName已经是商店的一个字段时,将它作为键似乎是多余的。另外,我不知道HashMap在迭代中设计得有多好

所以问题是:哪种方法是更好的设计实践,或者有更好的方法?程序员通常如何处理这种情况


不是重复的,因为这解释了这些方法的潜在问题。但是在codereview中可能会更好。

使用
HashMap
-显然这是您需要的抽象,因此它是最佳选择。
HashMap
上的迭代顺序为O(1)表示每个元素,O(n)表示整个映射的总迭代(注意
n
HashMap
的容量,而不是它的大小!)。您也可以使用(正如Peter Lawrey所建议的),但请注意:

性能可能略低于HashMap,这是由于维护链接列表的额外费用造成的,但有一个例外:在LinkedHashMap的集合视图上进行迭代需要与映射大小成比例的时间,而不管其容量如何。HashMap上的迭代可能会更加昂贵,需要与其容量成比例的时间

简言之,这将使迭代稍微快一点,而使其他操作稍微慢一点。想要更多的东西是不成熟的

尽管如此,如果您需要每一点点的速度,数据是相当静态的(即集合只创建[添加元素]一次,并多次使用[迭代,检查是否包含]),并且您不介意使用大约2倍的内存-您可以同时使用这两种内存,将二者相加,使用array/
ArrayList
进行迭代,使用
HashMap
进行查找。不过,我不建议随意使用它,因为它会使代码更难阅读和维护,而且很可能会违反规则。如果您打算使用它,我认为最好编写一个合成类,将
ArrayList
的迭代器与
Map
接口中的方法并行地公开


至于在对象中存储名称及其冗余,您只存储对键的引用,而不是键本身。因此,您的“损耗”(请注意,在大多数情况下不是真正的损耗)约为每个收集项4字节。除非你想拥有一个包含数十亿元素的集合,否则这不是问题。OTOH,问问自己为什么要在商店实例中存储商店名称?如果您希望能够在键(商店名称)和商店之间建立双射关系[能够通过名称获取商店并知道每个商店的名称]——您必须将名称存储在对象中,或者使用第二个映射。在大多数情况下,前者优于后者(这里,这更像是一个适当的抽象问题,而不是内存/CPU)。因此,在对象中复制密钥通常是处理它的最简单和最明显的方法。

使用
HashMap
-这显然是您需要的抽象,因此是最佳选择。
HashMap
上的迭代顺序为O(1)表示每个元素,O(n)表示整个映射的总迭代(注意
n
HashMap
的容量,而不是它的大小!)。您也可以使用(正如Peter Lawrey所建议的),但请注意:

性能可能略低于HashMap,这是由于维护链接列表的额外费用造成的,但有一个例外:在LinkedHashMap的集合视图上进行迭代需要与映射大小成比例的时间,而不管其容量如何。HashMap上的迭代可能会更加昂贵,需要与其容量成比例的时间

简言之,这将使迭代稍微快一点,而使其他操作稍微慢一点。想要更多的东西是不成熟的

尽管如此,如果您需要每一点点的速度,数据是相当静态的(即集合只创建[添加元素]一次,并多次使用[迭代,检查是否包含]),并且您不介意使用大约2倍的内存-您可以同时使用这两种内存,将二者相加,使用array/
ArrayList
进行迭代,使用
HashMap
进行查找。不过,我不建议随意使用它,因为它会使代码更难阅读和维护,而且很可能会违反规则。如果您打算使用它,我认为最好编写一个合成类,将
ArrayList
的迭代器与
Map
接口中的方法并行地公开

至于在对象中存储名称及其冗余,您只存储对键的引用,而不是键本身。因此,您的“损耗”(请注意,在大多数情况下不是真正的损耗)约为每个收集项4字节。除非你想拥有一个包含数十亿元素的集合,否则这不是问题。OTOH,问问自己为什么要在商店实例中存储商店名称?如果您希望能够在键(商店名称)和商店之间建立双射关系[能够通过名称获取商店并知道每个商店的名称]——您必须将名称存储在对象中,或者使用第二个映射。在大多数情况下,前者优于后者(这里,这更像是一个适当的抽象问题,而不是内存/CPU)。因此,在对象中复制密钥通常是si