什么Java集合认为排列相等? [英] What Java collection considers permutations to be equal?

查看:139
本文介绍了什么Java集合认为排列相等?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建可能包含重复值的集合,而不是特定的顺序。



换句话说:

  {1,1,2} == {2,1,1} == {1,2,1} 
pre>

事实上,我想有一组这些集合,所以如果我尝试添加 {1,1,2} / code>和 {2,1,1} ,第二个 .add()



如果我理解正确的话:



/ p>


  • ArrayList允许重复值,但具有固定顺序

  • HashSet允许顺序任意但不重复值

  • TreeSet确保顺序是常数,但不允许重复值



是否有一个我忽略的集合,允许重复的值和任意或固定顺序,以便两个相同元素的集合被认为相等?



< hr>

@asteri询问我的用例。在游戏中,我有不同长度的块,它们可以端到端地铺设一定距离。例如,如果距离是10,则可以用2-3-5或5-2-3或3-3-4或3-4-3或任何数量的其他排列来填充。根据可用的块,我想做一个列表,列出所有可能的集合,以解决填补空白。






自定义解决方案

@sprinter建议创建ArrayList的子类。 @dasblinkenlight和@Dici建议使用一个Map来存储 {Element:Count} 条目。我选择把这两个建议结合起来。下面是TreeMap的子类。键总是以相同的顺序存储,以确保hashCode()方法产生相同的值,例如具有相同的键和值。



increment 方法,以便于添加特定整数值的新出现。

  package com.example.treematch; 

import java.util.Map;
import java.util.TreeMap;

public class TreeMatch< K>扩展TreeMap< K,Integer> {

@Override
public boolean equals(Object other){
if(this == other){
return true;
}

if(!(TreeMatch的其他实例)){
return false;
}

TreeMatch otherMatch =(TreeMatch)other;
if(size()!= otherMatch.size()){
return false;
}

for(Object key:this.keySet()){
if(!otherMatch.containsKey(key)){
return false;
}
}

for(Object key:otherMatch.keySet()){
if(!this.containsKey(key)){
return假;
}

if(this.get(key)!= otherMatch.get(key)){
return false;
}
}

return true;
}

public void increment(K key){
Integer value;

if(this.containsKey(key)){
value =(this.get(key))+ 1;
} else {
value = 1;
}

this.put(key,value);
}


@Override
public int hashCode(){
int hashCode = 0;

for(Map.Entry entry:this.entrySet()){
hashCode + = entry.getKey()。hashCode();
hashCode = hashCode<< 1;
hashCode + = entry.getValue()。hashCode();
hashCode = hashCode<< 1;
}

return hashCode;
}
}


解决方案

Java内置库中没有任何内容,但Guava的 Multiset 这样做。


I want to create collections which may contain duplicate values, in no particular order.

In other words:

{ 1, 1, 2 } == { 2, 1, 1 } == { 1, 2, 1 }

In fact, I want to have a Set of these collections, so if I try to add both { 1, 1, 2 } and { 2, 1, 1 }, the second .add() will not actually do anything.

Is there a standard collection that already behaves this way?

If I understand correctly:

  • ArrayList allows for duplicate values, but has a fixed order
  • HashSet allows for the order to be arbitrary but no duplicate values
  • TreeSet ensures that the order is constant, but allows no duplicate values

Is there a collection that I have overlooked that allows for both duplicate values and either an arbitrary or a fixed order, so that two collections with the same elements are consider equal?


@asteri asked about my use case. In a game, I have blocks of different lengths which can be laid end to end to fill a certain distance. For example, if the distance is 10, it can be filled with 2-3-5 or 5-2-3 or 3-3-4 or 3-4-3, or any number of other permutations. Depending on what blocks are available, I want to make a list of all the possible collections that would solve fill the gap.


CUSTOM SOLUTION
@sprinter suggested creating a subclass of ArrayList. @dasblinkenlight and @Dici suggested using a Map to store { Element : Count } entries. I have chosen to combine these two suggestions. Below is a subclass of TreeMap. The keys are always stored in the same order, to ensure that the hashCode() method produces the same value for instance with the same keys and values.

I've used an increment method to make it easy to add a new occurrence of a particular integer "value".

package com.example.treematch;

import java.util.Map;
import java.util.TreeMap;

public class TreeMatch<K> extends TreeMap<K, Integer> {

  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }

    if (!(other instanceof TreeMatch)) {
      return false;
    }

    TreeMatch otherMatch = (TreeMatch) other;
    if (size() != otherMatch.size()) {
      return false;
    }

    for (Object key : this.keySet()) {
        if (!otherMatch.containsKey(key)) {
            return false;
        }
    }

    for (Object key : otherMatch.keySet()) {
      if (!this.containsKey(key)) {
        return false;
      }

      if (this.get(key) != otherMatch.get(key)) {
        return false;
      }
    }

    return true;
  }

  public void increment(K key) {
    Integer value;

    if (this.containsKey(key)) {
      value = (this.get(key)) + 1;
    } else {
      value = 1;
    }

    this.put(key, value);
  }


  @Override
  public int hashCode() {
    int hashCode = 0;

    for (Map.Entry entry : this.entrySet()) {
      hashCode += entry.getKey().hashCode();
      hashCode = hashCode << 1;
      hashCode += entry.getValue().hashCode();
      hashCode = hashCode << 1;
    }

    return hashCode;
  }
}

解决方案

There's nothing in the Java built-in libraries, but Guava's Multiset does this.

这篇关于什么Java集合认为排列相等?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆