简体   繁体   English

我应该使用什么样的Java集合?

[英]What kind of Java collection should I use for this?

I am fairly new to Java and am having trouble understanding the differences between different collections. 我是Java的新手,我很难理解不同集合之间的差异。 I have a list of 19 resources. 我有19个资源的清单。 Each resource is assigned a hex color. 为每个资源分配一个十六进制颜色。 I want to get a random resource with its color and use that resource with my code. 我想获得一个随机资源及其颜色,并将该资源与我的代码一起使用。 Once I am finished with the current resource, I want to remove it from the list so that only a certain number of resources are used. 完成当前资源后,我想将其从列表中删除,以便只使用一定数量的资源。

Should I use a dictionary, map, or hashtable? 我应该使用字典,地图还是哈希表? Or any others that I am missing. 或者我失踪的任何其他人。

What you could do, is store your resources into a List , then randomly permutes it thanks to Collections.shuffle(List<?> list) or shuffle(List<?> list, Random rnd) , and finally call iterator() on the resulting list to get an instance of Iterator that you could store into a member field to be able to iterate over your list (thanks to hasNext() / next() ) and remove your resource once done with remove() . 您可以做的是将资源存储到List ,然后通过Collections.shuffle(List<?> list)shuffle(List<?> list, Random rnd)随机置换它,最后调用iterator()生成列表以获取Iterator的实例,您可以将其存储到成员字段中以便能够遍历您的列表(感谢hasNext() / next() )并在使用remove()完成后删除您的资源。

Here is a pseudo code using String as resource just to show the idea: 这是一个使用String作为资源的伪代码,只是为了表明这个想法:

// Create a read/write list (Arrays.asList returns a read-only list)
List<String> resources = new ArrayList<>(Arrays.asList("1", "2", "3"));
System.out.printf("Initial state = %s%n", resources);
Collections.shuffle(resources);
System.out.printf("Permuted List = %s%n", resources);
Iterator<String> iterator = resources.iterator();
if (iterator.hasNext()) {
    String resource = iterator.next();
    // do something
    iterator.remove();
    System.out.printf("After remove = %s%n", resources);
}

Output: 输出:

Initial state = [1, 2, 3]
Permuted List = [3, 1, 2]
After remove = [1, 2]

NB: This approach makes sense in your case as you have a small list, please note that if you have a big list and you intend to retrieve only a small part of it, you should consider using a Random to get randomly the index of the next element (using nextInt(int bound) with list.size() as parameter) to get (using get(int index) ) and remove (using remove(int index) ) instead of using Collections.shuffle(List<?> list) as it would cause an overhead. 注意:这种方法在你的情况下是有意义的,因为你有一个小列表,请注意,如果你有一个大的列表,并且你打算只检索它的一小部分,你应该考虑使用Random获取随机的索引下一个元素(使用nextInt(int bound)list.size()作为参数)获取(使用get(int index) )和remove(使用remove(int index) )而不是使用Collections.shuffle(List<?> list)因为它会导致开销。


ArrayList wouldn't work because I need to assign the color(value) to the resource(key) ArrayList不起作用,因为我需要将颜色(值)分配给资源(键)

Yes it can work if you use a List of a wrapper class that will contain both, your color and your resource (for example AbstractMap.SimpleImmutableEntry or simply a custom class). 是的,如果您使用包含颜色和资源的包装类的List (例如AbstractMap.SimpleImmutableEntry或只是一个自定义类),它可以工作。 It is good enough as you don't seem to need to retrieve the color by resource. 这很好,因为您似乎不需要按资源检索颜色。 If you do, you could simply have a Map with resource as key and color as value and use new ArrayList<>(map.keySet()) to initialize your list of resources, then you will be able to apply what is proposed previously in this answer. 如果你这样做,你可以简单地有一个Map以资源为重点和颜色值,并使用new ArrayList<>(map.keySet())来初始化你的资源列表,然后你就可以申请什么是先前提出这个答案。

If you want to lookup (get) resource based on its hex use following 如果要根据其十六进制使用查找(获取)资源,请执行以下操作

// Initialize
Map<String, Resource> resourceMap = new HashMap<>();
resourceMap.put("hex1", hex1Resource);
resourceMap.put("hex2", hex3Resource);
resourceMap.put("hex3", hex3Resource);

// Get specific
Resource hex2Resource = resourceMap.get("hex2");
resourceMap.remove("hex2");

If you want to lookup resource randomly, there are 2 options 如果要随机查找资源,有2个选项

  • Use List (this allows duplicates) 使用列表(这允许重复)
  • Use Set (stores only unique values) 使用Set(仅存储唯一值)

Using Lists 使用列表

// Initialize
List<Resource> list = new ArrayList<>();
list.add(resource1);
list.add(resource2);
list.add(resource3);

// Get random
Random rand = new Random();
Resource randomResource = list.get(rand.nextInt(list.size()));

// Delete the element from list
list.remove(randomResource);

Using Sets 使用集合

// Initialize
Set<Resource> set = new HashSet<>();
set.add(resource1);
set.add(resource2);
set.add(resource3);

// Convert to List, since Set does not have get(int) method. 
List<Resource> list = new ArrayList<>(set);

// Get random
Random rand = new Random();
Resource randomResource = list.get(rand.nextInt(list.size()));

// Delete the element from list
list.remove(randomResource);

Note : For both cases above, Resource class will need to implement methods equals and hashcode so that list/set can compare elements and work correctly. 注意 :对于上述两种情况,Resource类需要实现equals和hashcode方法,以便list / set可以比较元素并正常工作。 See Java equals and hashcode 请参阅Java equals和hashcode

Update : Sets do not have get(int) method. 更新 :集合没有get(int)方法。 Updated the code to fix this. 更新了代码以解决此问题。

The following should work. 以下应该有效。 The steps are: 步骤是:

  1. Create a list of Resource 创建资源列表
  2. Generate a random number and get the item 生成随机数并获取该项目
  3. Do what you want to do with your random item 做你想做的随机物品
  4. Remove it from list 从列表中删除它

Example Code: 示例代码:

 //1
List<Resource> resources= getList();

//2
Random generator = new Random();
Resource randomResource = resources.get(generator.nextInt(resources.size() -1));

//3
//do your stuff

//4
resources.remove(randomResource);

Resource can be a class which wraps your data 资源可以是包装数据的类

class Resource{
    String color;
    String otherProperties;
    //..


    @Override
    public boolean equals(Object obj) {
        //generate from IDE or write one
    }

    @Override
    public int hashCode() {
        //generate from IDE or write one
    }
}

Blockquote 大段引用

if u need random order better you can go for List object. 如果你需要更好的随机顺序,你可以去List对象。

List<String> resourceMap = new CopyOnWriteArrayList<>();
          resourceMap.add("hex1");
          resourceMap.add("hex2");
          resourceMap.add("hex3");
          resourceMap.add("hex4");
          Collections.shuffle(resourceMap);
          resourceMap.forEach(resource->{
              resourceMap.remove(resource);
          });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM