在集合中重复对象存储

时间:2013-07-22 19:10:38

标签: java coding-style

考虑一个带有以下接口的简单对象存储:

// add an object with ‘blob’ content into the system and return an id
int put(string blob); 

// retrieve the contents of an object identified by ‘id’. NULL if doesn’t exist
string get(int); 

// delete an object identified by ‘id’
void delete(int id); 

//number of (non duplicate) objects stored in the object store
int size(); 

要求
对象库必须重复删除对象。如果相同的字节序列存储两次 - 那么存储不能存储两次数据。对象 可以相当大 - 比如说 - 大小从1K到5MB不等。 Blob是不可变的.. 我们正在寻找这些API调用的标准顺序一致性语义。如果某个对象被“放入” - 那么下一个即时“获取”调用 - 应该返回先前放置的值。例如。如果客户端执行以下操作:

Id = objectstore.put(data);
data1 = objectstore.get(id);

第二个操作必须返回与'data'指向的字节序列相同的字节。没有其他客户端/进程/线程应该能够 干扰那个。

到目前为止我的代码:

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class ObjectStore {

String blobString;
Object objectId;

public ObjectStore(String blobString, Object objectId) {

    this.blobString = blobString;
    this.objectId = objectId;
}

@Override
public boolean equals(Object o){

    if(!(o instanceof ObjectStore)){
        return false;
    }
    if((o == null) || (o.getClass() != this.getClass()))
        return false;
    // object must be Test at this point
    ObjectStore store = (ObjectStore)o;
    return blobString.toString() == store.blobString &&
        (objectId != null && objectId.equals(store.objectId));
}

@Override
public int hashCode() {
    int hash = 7;
    hash = 31 * hash + blobString.hashCode();
    hash = 31 * hash + ((objectId == null) ? 0 : objectId.hashCode());

    return hash;
}

Set<String> set = new HashSet<String>();

   /**
   * Put object into store and return id.
   * @param blobString
   * @return
   */
  public int put(String blobString) {
      set.add(blobString);
    return 0;
  }

  /**
   * Get object corresponding to id. Return null if no such object exists.
   * @param objectId
   * @return
   */
  public String get(int objectId) {

    return null;
  }

  /**
   * Release object - don't need it anymore.
   * @param objectId
   */
  public void delete(int objectId) {
    // stub
  }

  /**
   * Number of distinct blobs stored in the objectStore
   * @return
   */
  public int size() {
    // stub
    return 0;
  }

public static void main(String[] args) {

    Map<String, Object> map = new HashMap<String, Object>();


}

}

我无法确定我需要使用Map或Set接口,因为put()方法返回对象id。

1 个答案:

答案 0 :(得分:0)

在将对象映射到整数ID时使用Map。集合不一定映射数据,它们只是没有重复元素的集合。

但是,由于您似乎在编写接口,因此实现的内部结构无关紧要。使用最有效的方法,并使用接口要求。

编辑2:

如果我实现这个,我会使用整数来生成put操作的唯一ID。这将提供最多约40亿put次操作的独特ID。

还需要第二张地图来检查之前是否添加了一些blob序列。这样您就可以使用与第一次相同的密钥替换旧blob。

int idProvider=0;
HashMap<Integer, String> map1 = new HashMap<Integer, String>();
HashMap<String, Integer> map2 = new HashMap<String, Integer>();
public int put(String blob){
    int id = -1;
    if(map2.containsKey(blob)){
        id = map2.get(blob);
    }else{
        id = idProvider;
        idProvider+=1;
        map2.put(blob, id);
    }
    map1.put(id, blob);
    return id;
}
public void delete(int id){
    String blob = map1.remove(id);
    if(blob!=null){
        map2.remove(blob);
    }
}
String get(int id){
    String blob = map1.get(id);
    return blob;
}
int size(){
    return map1.size();
}

这应该符合您问题中的所有条件,除非线程安全是个问题。如果是这种情况,只需同步访问。我编译并测试了这段代码。

测试:

    ObjectStore store = new ObjectStore();
    int id1 = store.put("hello");
    int id2 = store.put("world");
    int id3 = store.put("world");
    if(store.size()!=2)
        throw new RuntimeException("Wrong size");
    if (id2 != id3)
        throw new RuntimeException("Ids not equal?");
    String strHello = store.get(id1);
    String strWorld = store.get(id3);
    if (!strHello.equals("hello") || !strWorld.equals("world"))
        throw new RuntimeException();
    store.delete(id3);
    String strShouldBeNull = store.get(id3);
    if(strShouldBeNull!=null)
        throw new RuntimeException();