我需要在程序中组织灵活的数据结构方面的建议。 看,我要组织一下看起来像二维数组的数据结构 喜欢
double[][] arr = new double[10][10];
如果您需要设置或获取此数组的某些元素,您将编写类似
的内容double x=arr[i,j]; // arr[i,j]=y;
其中i和j是int数字
但是在我的程序中我需要像
这样的东西double k=arr[obj1,obj2]
其中obj1和obj2是对象
我有一个想法--HashMap可以解决我的问题
所以它看起来像
class Coordinates {
Object1 obj1;
Object2 obj2;
//TODO override equals() method
Coordinates(Object1 obj1, Object2 obj2) {
this.obj1=obj1;
this.obj2=obj2;
}
}
...
HashMap<Coordinates, Double> semiTwoDimArray=new HashMap<Coordinates, Double>();
并且元素的设置和获取看起来像
semiTwoDimArray.put(new Coordinates(obj1, obj2), 3.14);
和获得可能是
double pi = semiTwoDimArray.get(new Coordinates(obj1, obj2));
但至于我: 1)这种实现在迭代行或列时存在问题(操作太多) 2)看起来不优雅
有人可以建议我更好的解决方案吗?
答案 0 :(得分:2)
您可以将结构包装到一个类中,并提供漂亮而干净的get(Object,Object)
和set(Object,Object,double)
方法。
这样,不雅的代码将包含在类中,每次访问结构时都不需要重复。
如果您发现原始选择不是最佳的,这也可以轻松更改基础数据结构。
答案 1 :(得分:0)
正如您所说,HashMap<Coordinate, Value>
结构不允许您遍历行或列。
如果需要,那么这肯定不是正确的数据结构。
一些想法:
使用嵌套地图:Map<RowKey, Map<ColumnKey, Value>>
或Map<ColumnKey, Map<RowKey, Value>>
- 一个支持遍历行,另一个支持遍历列。也许你需要同时拥有这两种结构。
使用一个地图进行直接访问,另外还有按行/列进行迭代的列表。
使用为此目的而制作的数据结构(我现在可以想象一个2D-hashmap)。
首先,您需要列出您的需求,甚至可以分析有多少对象,每列和每行中有多少(性能特征将取决于此)。你有任意对象,还是某些关键类型的对象?这种类型可比吗?
以下是 aix 建议的示例界面:
package de.fencing_game.paul.examples;
import java.util.*;
/**
* A map with two keys.
*
* @see java.util.Map
*
* @param <K1> the first key type.
* @param <K2> the second key type.
* @param <V> the value type.
*/
public interface Map2D<K1,K2,V> {
/**
* A pair of keys for our map.
*/
public interface KeyPair<K1,K2> {
public K1 getKey1();
public K2 getKey2();
/**
* returns the hashCode of this entry.
* The hashcode is defines as
* {@code getKey1().hashCode() * 13 + getKey2().hashCode() * 17}
* If one of these objects is {@code null}, replace 0 for
* its hash code.
*/
public int hashCode();
/**
* compares this entry to another object. An object {@code that} is
* equal this entry, if and only if it is also an Map2D.KeyPair, and
* {@code
* this.getKey1().equals(that.getKey1()) &&
* this.getKey2().equals(that.getKey2());
* }
*/
public boolean equals(Object that);
}
/**
* an entry in our map, consisting of two keys and a value.
* @see Map.Entry
*/
public interface Entry<K1,K2,V> {
public K1 getKey1();
public K2 getKey2();
public V getValue();
public V setValue(V val);
/**
* returns the hashCode of this entry.
* The hashcode is defines as
* {@code getKey1.hashCode() * 7 + getKey2().hashCode() * 3 +
* getValue().hashCode() * 5 }
* If one of these objects is {@code null}, replace 0 for
* its hash code.
*/
public int hashCode();
/**
* compares this entry to another object. An object {@code that} is
* equal this entry, if and only if it is also an Map2D.Entry, and
* {@code
* this.getKey1().equals(that.getKey1()) &&
* this.getKey2().equals(that.getKey2()) &&
* this.getValue().equals(that.getValue());
* }
*/
public boolean equals(Object that);
}
/**
* the number of mappings in this map.
*/
public int size();
/**
* returns true if this map is empty.
*/
public boolean isEmpty();
/**
* returns true if this map contains a mapping for the specified key pair.
*/
public boolean containsKeys(Object key1, Object key2);
/**
* returns true if this map contains a mapping with this
* specified key as first key.
*/
public boolean containsKey1(Object key1);
/**
* returns true if this map contains a mapping with this
* specified key as second key.
*/
public boolean containsKey2(Object key2);
/**
* returns true if this map contains a mapping with the
* specified value.
*/
public boolean containsValue(Object value);
/**
* retrieves an element from the map.
* @return null if there is no such pair of keys, else the value.
*/
public V get(K1 key1, K2 key2);
/**
* puts a new element in the map.
* @return the old value, or null, if there was no such mapping.
*/
public V put(K1 key1, K2 key2, V value);
/**
* removes a mapping from this map.
*/
public V remove(Object key1, Object key2);
/**
* puts all mappings from the specified 2d-map into this map.
*/
public void putAll(Map2D<? extends K1, ? extends K2, ? extends V> map);
/**
* clears this map.
*/
public void clear();
/**
* returns a collection view of the values of this map.
*/
public Collection<V> values();
/**
* returns a collection view of this map's entries.
*/
public Set<Map2D.Entry<K1,K2,V>> entrySet();
/**
* returns a map view as a map of key-pairs to values.
*/
public Map<KeyPair<K1,K2>, V> flattedMap();
/**
* returns a map view as a map of maps, by first key first.
*/
public Map<K1, Map<K2, V>> projection1Map();
/**
* returns a map view as a map of maps, by second key first.
*/
public Map<K2, Map<K1, V>> projection2Map();
/**
* compares this map with another object.
* This Map2D is equal to another object only if it also is a Map2D
* and these equivalent conditions hold:
* <ul>
* <li>{@code this.entrySet().equals(that.entrySet())}</li>
* <li>{@code this.flattedMap().equals(that.flattedMap())}</li>
* <li>{@code this.projection1Map().equals(that.projection1Map())}</li>
* <li>{@code this.projection2Map().equals(that.projection2Map())}</li>
* </ul>
*/
public boolean equals(Object that);
/**
* The hashCode is defined as the {@link #entrySet()}{@code .hashCode()}.
*/
public int hashCode();
}
我稍后会添加一些示例实现。