看看谁的算法效率优,消耗内存最少 我有1个需求,是实现1个id,对应多个对象。用map的话,第二次put同一个id的时候会把之前的value覆盖,这个大家都知道。然后需要通过id,查找他对应的所有对象。看看大家有什么好想法,我实现了但是我感觉占地内存不少。。如果数据量大,内存吃紧。谢谢大家了就搞个 100 分吧。呵呵 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我也用这个,可是你有没有想过,arraylist如果申请 1000,10000个会是多大的内存消耗,而且你可能用到的某1个arraylist 也只是几个,都浪费了大虾 一般情况下就这个够了,如果预先知道对象的个数的话使用List也不会浪费空间。如果真的在这个地方是性能瓶颈,那只能根据特殊情况采取特殊的处理,那是case by case的事情。 HashMap<String,String> KeyMap=new HashMap<String,String>();HashMap<String,String> etyMap=new HashMap<String,String>();添加对象的时候String sGuid=getGuid();etyMap.push(sGuid,obj);ids=(keyMap.get(id)!=null?keyMap.get(id):"")+sGuid;keyMap.put(id,ids); 晕,id之间应该有个分隔符的ids=(keyMap.get(id)!=null?keyMap.get(id):"")+"|"+sGuid; HashMap<String, ArrayList<yourObject>> map;...map.get(key).add(value);//添加...map.get(key)//返回对应的LIST... 楼上的你写的什么啊。。etyMap.push(sGuid,obj);这个是新方法吗? 都说过这个方法极大的浪费arraylist了而且可能要申请 n多 arraylist 写错了,push是stack的方法,应该是put,刚刚还在写堆栈操作程序,有点乱了 public class OBJ { protected ArrayList<YourObj> list; public OBJ() { list = new ArrayList<YourObj>(); } public ArrayList<YourObj> getItems(String key) { ArrayList<YourObj> reList = new ArrayList<YourObj>(); for(int i = 0; i < list.size(); i++) { YourObj obj = list.get(i); if(obj.getId().equals(key)) { reList.add(obj); } } } public void add(YourObj obj) { .... }}参考着干吧,效率太低了,我都不好意思! 我新手,想了一下也就会这个HashMap <String,ArrayList>,期待大虾们的回答。 HashMap<String,HashSet<myClass>>也可以。 还有一种方法,ID设为String型HashMap<String, Integer> keyLenList;HashMap<String, YourObj> valueList;//这个结构类似:"key_1"、"key_2"get(key) { ArrayList reList... for(int i = 0; i < keyLenList.get(key); i++) { StringBuffer strKey = key.append("_").append(i); reList.add(valueLis.get(strKey)); } return reList;}...就写这么多了... 我想到点东西。。LZ的问题是不是跟输入法类似比如:我输入Sh的时候,表示的意思可能是“时候”,也可以是“上海”。如果输入的是kj的话,表示的意思可以是“烤鸡”,可以是“空间”,可以是“科技”,也可以是“看见”想到就这么多了 import java.util.*;class MyClass implements Comparable<MyClass>{ String name; //other.... MyClass(String name){ this.name=name; } //geters .... //seters..... public int compareTo(MyClass mc){ return name.compareTo(mc.name); // } public boolean equals(MyClass mc){ if(name.equals(mc.name)){ return true; } return false; } public String toString(){ return name; }}public class MyCollection{ private HashMap<String,TreeSet<MyClass>> myMap=new HashMap<String,TreeSet<MyClass>>(); public void put(String id,MyClass mc){ TreeSet<MyClass> tree=myMap.get(id); if(tree==null){ TreeSet<MyClass> treeA=new TreeSet<MyClass>(); treeA.add(mc); myMap.put(id,treeA); }else{ tree.add(mc); } } public TreeSet<MyClass> get(String id){ return myMap.get(id); } public void printAll(String id){ TreeSet<MyClass> tree=myMap.get(id); for(MyClass mc:tree){ System.out.println(mc); } } public static void main(String[] args){ MyCollection myCollection=new MyCollection(); myCollection.put("1",new MyClass("one")); myCollection.put("2",new MyClass("two")); myCollection.put("1",new MyClass("oneone")); myCollection.put("1",new MyClass("one")); myCollection.put("2",new MyClass("twotwo")); myCollection.printAll("1"); }}//之所以MyClass 实现了Comparable以及用了TreeSet,是为了查找一个对象方便,可以遍历整个myMap来查。但这个问题和你的要求没有关系。//用TreeSet还有一意思是相同的对象就没有必要再放进去了。 我在想能不能改变对象的构造,比如往对象中封装一个id变量,存储的是这些对象对应的id,然后将所有的对象放入一个ArrayList中,要根据id获得对象,那么就写个方法,循环这个arrayList。得到这个id对应的所有的对象比如 class Po { private long id; } 有个方法叫做getPos(id) 返回就可以了 改用泛型,23楼和27楼的想法就可以实现了。import java.util.*;class MyClass implements Comparable<MyClass>{ String name; //other.... MyClass(String name){ this.name=name; } //geters .... //seters..... public int compareTo(MyClass mc){ return name.compareTo(mc.name); // } public boolean equals(MyClass mc){ if(name.equals(mc.name)){ return true; } return false; } public String toString(){ return name; }}public class MyCollection<T extends Comparable<T>>{ private HashMap<String,TreeSet<T>> myMap=new HashMap<String,TreeSet<T>>(); public void put(String id,T mc){ TreeSet<T> tree=myMap.get(id); if(tree==null){ TreeSet<T> treeA=new TreeSet<T>(); treeA.add(mc); myMap.put(id,treeA); }else{ tree.add(mc); } } public TreeSet<T> get(String id){ return myMap.get(id); } public void printAll(String id){ TreeSet<T> tree=myMap.get(id); for(T mc:tree){ System.out.println(mc); } } public static void main(String[] args){ MyCollection<MyClass> myCollection=new MyCollection<MyClass>(); myCollection.put("1",new MyClass("one")); myCollection.put("2",new MyClass("two")); myCollection.put("1",new MyClass("oneone")); myCollection.put("1",new MyClass("one")); myCollection.put("2",new MyClass("twotwo")); myCollection.printAll("1"); MyCollection<String> words=new MyCollection<String>(); words.put("sh","上海"); words.put("sh","似乎"); words.put("kj","会计"); words.put("sh","嗜好"); words.put("kj","空间"); words.put("sh","山河"); words.put("kj","看见"); System.out.println("sh:"); words.printAll("sh"); System.out.println("kj:"); words.printAll("kj"); }}//之所以MyClass 实现了Comparable以及用了TreeSet,是为了查找一个对象方便,可以遍历整个myMap来查。但这个问题和你的要求没有关系。//用TreeSet还有一意思是相同的对象就没有必要再放进去了。结果:F:\java>java MyCollectiononeoneonesh:上海似乎嗜好山河kj:会计看见空间 直接使用HashMap<String,String>可以吗?Map<String,obj> a = new HashMap<String,obj>关键是这个String存储的时候用id+标识位,然后拿的时候只要给出id就行啦,只要保证key不同不就好了,不需要用到set或者list 你要不怕麻烦就自己重写HashMap-------------------------------- public HashMap<String,List> getDocApp(ParamsContext pcn) { HashMap<String,List> hsm=new HashMap<String,List>(); Query query=getSession().getNamedQuery("GetTaskApprove"); query.setParameter("docId", pcn.getDocId()); List tmp=query.list(); String taskId=""; int fromIndex=0, toIndex=0; for (Iterator iter=tmp.iterator(); iter.hasNext();) { Object[] result=(Object[])iter.next(); if(taskId==null||taskId.equals("")){ taskId=result[0].toString(); } if(result[0].toString().equals(taskId)){ toIndex++; continue; }else{ hsm.put(taskId, tmp.subList(fromIndex, toIndex)); fromIndex=toIndex; toIndex++; taskId=result[0].toString(); } } hsm.put(taskId, tmp.subList(fromIndex, tmp.size())); return hsm; } 谢谢小虫子同学有关系啊,Sh不相当于ID,中文的String不就跟对象一样不过25楼的想法我也想过的,不过楼主不是说没关系嘛其实25楼的是我的最初想法,就是搜索的时间代价太大 不知道什么算法才能让你惊喜.HashMap算法中,get方法的时间复杂度为O(1)。空间复杂度为O(n)n=你放进去的不重复对象的个数。从TreeSet中拿出所有的元素的时间复杂度为O(n)n=相同id的对象个数。 类似于这样不行吗?给点伪代码(其中的"sh","kj"相当于你的id)long n =0L;Map<String,String> loc = new HashMap<String,String>;loc.put("sh"+n,"上海");n++;loc.put("sh"+n,"似乎");n++;loc.put("sh"+n,"山河");n++;loc.put("kj"+n,"会计");n++;loc.put("kj"+n,"看见");n++;loc.put("kj"+n,"空间");n++;//只要put后自增就可以for(String s:loc.getKeys()){ if(s.subString(0,2).equals("sh")){ //这里随便用一个集合或者数组去存放对象 } if(s.subString(0,2).equals("kj")){ //这里随便用一个集合或者数组去存放对象 }}就这样啊,如果只是存放,也就不需要list或者set,map中最多也就是你对象的封装类型和key有对应关系的存放最适合的就是map了,不知道还有哪位大大有更好的方法 25楼的是节省了空间,但牺牲了时间。我有一个大致的想法不知道合不合要求。就是用一个ARRAY来装你的所有对象,MAP来装(ID, “对象在ARRAY中位序1|| 对象在ARRAY中位序2|| 对象在ARRAY中位序3|| ” )这样通过ID可以取得 “对象在ARRAY中位序1|| 对象在ARRAY中位序2|| 对象在ARRAY中位序3|| ”再split, 到array中取你要的对象。 此言差矣,ArrayList可以自动扩展长度,即使你真的要放1000,10000个,也不一定在初始化的时候就设置为这么大。另外,ArrayList有个方法叫作trimToSize(); 你可以在不插入数据的时候调用一下 用缓存吧 比如说你要申请一千个数据,你可以一百个一百个的申请 分为十次申请 然后在把一百个作为一个整体放到HashMap 最后在内存中虽然也存在1000个地址 但因为他是分为十个整体存在的 相对而言他消耗的内存要小 可以尝试用 HashMap 内插一个 list 两个容器嵌套或者直接用 LinkList 效率比较高! Map<Object,String> key 放 对象value 放 id这样满足楼主的需要,不会被覆盖了。 兄弟你通过 vaule 去找 id???你好猛啊 public class MyObject{ //待保存的对象类。}public class Collector{ private Map<Integer,Object> buff = new HashMap<Integer,Object>(); private List<MyObject> createList(){ return new LinkedList<MyObject>(); } public void put(Integer id,MyObject obj){ Object o = buff.get(id); if(o==null){ buff.put(id,obj); }else if(o instanceof List)[ ((List)o).add(obj); }else{ List<MyObject> list = createList(); list.add((MyObject)o); list.add(obj); buff.put(id,list); } } public List<MyObject> getMyObjectList(int id){ Object o = buff.get(id); if(o==null)return null; else if(o instanceof List){ return (List)o; }else{ List<MyObject> list = new ArrayList<MyObject>(1); list.add((MyObject)o); return list; } }}List可以换成Set,这样就不会有重复的对象保存到Set当中去。 请教一个关于系统会话时间设置的问题 如何令JInternalFrame 默认最大化? 新手关于学习Java中遇到问题 cavaj反编译.class遇到内部类出错 JAVA+C#=? socket通讯,CPU使用率100%,如何解决 迷茫的初学者 按钮响应图片加速移动? #7 Problem: Oracle的SQLCODE问题 JSON : No converter found for return value of type 双精度型转换的问题 是不是用j2ee和j2me可以实现的用j2se都可以实现?
HashMap<String,String> etyMap=new HashMap<String,String>();
添加对象的时候
String sGuid=getGuid();
etyMap.push(sGuid,obj);ids=(keyMap.get(id)!=null?keyMap.get(id):"")+sGuid;
keyMap.put(id,ids);
ids=(keyMap.get(id)!=null?keyMap.get(id):"")+"|"+sGuid;
...
map.get(key).add(value);//添加
...
map.get(key)//返回对应的LIST
...
楼上的你写的什么啊。。
etyMap.push(sGuid,obj);
这个是新方法吗?
都说过这个方法极大的浪费arraylist了而且可能要申请 n多 arraylist
protected ArrayList<YourObj> list;
public OBJ() {
list = new ArrayList<YourObj>();
} public ArrayList<YourObj> getItems(String key) {
ArrayList<YourObj> reList = new ArrayList<YourObj>();
for(int i = 0; i < list.size(); i++) {
YourObj obj = list.get(i); if(obj.getId().equals(key)) {
reList.add(obj);
}
}
} public void add(YourObj obj) {
....
}
}参考着干吧,效率太低了,我都不好意思!
HashMap<String, YourObj> valueList;//这个结构类似:"key_1"、"key_2"get(key) {
ArrayList reList...
for(int i = 0; i < keyLenList.get(key); i++) {
StringBuffer strKey = key.append("_").append(i);
reList.add(valueLis.get(strKey));
} return reList;
}
...就写这么多了...
LZ的问题是不是跟输入法类似
比如:我输入Sh的时候,表示的意思可能是“时候”,也可以是“上海”。
如果输入的是kj的话,表示的意思可以是“烤鸡”,可以是“空间”,可以是“科技”,也可以是“看见”
想到就这么多了
class MyClass implements Comparable<MyClass>{
String name;
//other....
MyClass(String name){
this.name=name;
}
//geters ....
//seters.....
public int compareTo(MyClass mc){
return name.compareTo(mc.name); //
}
public boolean equals(MyClass mc){
if(name.equals(mc.name)){
return true;
}
return false;
}
public String toString(){
return name;
}
}public class MyCollection{
private HashMap<String,TreeSet<MyClass>> myMap=new HashMap<String,TreeSet<MyClass>>();
public void put(String id,MyClass mc){
TreeSet<MyClass> tree=myMap.get(id);
if(tree==null){
TreeSet<MyClass> treeA=new TreeSet<MyClass>();
treeA.add(mc);
myMap.put(id,treeA);
}else{
tree.add(mc);
}
}
public TreeSet<MyClass> get(String id){
return myMap.get(id);
}
public void printAll(String id){
TreeSet<MyClass> tree=myMap.get(id);
for(MyClass mc:tree){
System.out.println(mc);
}
}
public static void main(String[] args){
MyCollection myCollection=new MyCollection();
myCollection.put("1",new MyClass("one"));
myCollection.put("2",new MyClass("two"));
myCollection.put("1",new MyClass("oneone"));
myCollection.put("1",new MyClass("one"));
myCollection.put("2",new MyClass("twotwo"));
myCollection.printAll("1");
}}
//之所以MyClass 实现了Comparable以及用了TreeSet,是为了查找一个对象方便,可以遍历整个myMap来查。但这个问题和你的要求没有关系。
//用TreeSet还有一意思是相同的对象就没有必要再放进去了。
{
private long id;
} 有个方法叫做getPos(id)
返回就可以了
class MyClass implements Comparable<MyClass>{
String name;
//other....
MyClass(String name){
this.name=name;
}
//geters ....
//seters.....
public int compareTo(MyClass mc){
return name.compareTo(mc.name); //
}
public boolean equals(MyClass mc){
if(name.equals(mc.name)){
return true;
}
return false;
}
public String toString(){
return name;
}
}public class MyCollection<T extends Comparable<T>>{
private HashMap<String,TreeSet<T>> myMap=new HashMap<String,TreeSet<T>>();
public void put(String id,T mc){
TreeSet<T> tree=myMap.get(id);
if(tree==null){
TreeSet<T> treeA=new TreeSet<T>();
treeA.add(mc);
myMap.put(id,treeA);
}else{
tree.add(mc);
}
}
public TreeSet<T> get(String id){
return myMap.get(id);
}
public void printAll(String id){
TreeSet<T> tree=myMap.get(id);
for(T mc:tree){
System.out.println(mc);
}
}
public static void main(String[] args){
MyCollection<MyClass> myCollection=new MyCollection<MyClass>();
myCollection.put("1",new MyClass("one"));
myCollection.put("2",new MyClass("two"));
myCollection.put("1",new MyClass("oneone"));
myCollection.put("1",new MyClass("one"));
myCollection.put("2",new MyClass("twotwo"));
myCollection.printAll("1");
MyCollection<String> words=new MyCollection<String>();
words.put("sh","上海");
words.put("sh","似乎");
words.put("kj","会计");
words.put("sh","嗜好");
words.put("kj","空间");
words.put("sh","山河");
words.put("kj","看见");
System.out.println("sh:");
words.printAll("sh");
System.out.println("kj:");
words.printAll("kj");
}}
//之所以MyClass 实现了Comparable以及用了TreeSet,是为了查找一个对象方便,可以遍历整个myMap来查。但这个问题和你的要求没有关系。
//用TreeSet还有一意思是相同的对象就没有必要再放进去了。结果:
F:\java>java MyCollection
one
oneone
sh:
上海
似乎
嗜好
山河
kj:
会计
看见
空间
Map<String,obj> a = new HashMap<String,obj>
关键是这个String
存储的时候用id+标识位,然后拿的时候只要给出id就行啦,只要保证key不同不就好了,不需要用到set或者list
public HashMap<String,List> getDocApp(ParamsContext pcn) {
HashMap<String,List> hsm=new HashMap<String,List>();
Query query=getSession().getNamedQuery("GetTaskApprove");
query.setParameter("docId", pcn.getDocId());
List tmp=query.list();
String taskId="";
int fromIndex=0, toIndex=0;
for (Iterator iter=tmp.iterator(); iter.hasNext();) {
Object[] result=(Object[])iter.next();
if(taskId==null||taskId.equals("")){
taskId=result[0].toString();
}
if(result[0].toString().equals(taskId)){
toIndex++;
continue;
}else{
hsm.put(taskId, tmp.subList(fromIndex, toIndex));
fromIndex=toIndex;
toIndex++;
taskId=result[0].toString();
}
}
hsm.put(taskId, tmp.subList(fromIndex, tmp.size()));
return hsm;
}
有关系啊,Sh不相当于ID,中文的String不就跟对象一样
不过25楼的想法我也想过的,不过楼主不是说没关系嘛其实25楼的是我的最初想法,就是搜索的时间代价太大
不知道什么算法才能让你惊喜.HashMap算法中,get方法的时间复杂度为O(1)。空间复杂度为O(n)n=你放进去的不重复对象的个数。
从TreeSet中拿出所有的元素的时间复杂度为O(n)n=相同id的对象个数。
long n =0L;
Map<String,String> loc = new HashMap<String,String>;
loc.put("sh"+n,"上海");
n++;
loc.put("sh"+n,"似乎");
n++;
loc.put("sh"+n,"山河");
n++;
loc.put("kj"+n,"会计");
n++;
loc.put("kj"+n,"看见");
n++;
loc.put("kj"+n,"空间");
n++;
//只要put后自增就可以
for(String s:loc.getKeys()){
if(s.subString(0,2).equals("sh")){
//这里随便用一个集合或者数组去存放对象
}
if(s.subString(0,2).equals("kj")){
//这里随便用一个集合或者数组去存放对象
}
}
就这样啊,如果只是存放,也就不需要list或者set,map中最多也就是你对象的封装类型和key
有对应关系的存放最适合的就是map了,不知道还有哪位大大有更好的方法
我有一个大致的想法不知道合不合要求。
就是用一个ARRAY来装你的所有对象,
MAP来装(ID, “对象在ARRAY中位序1|| 对象在ARRAY中位序2|| 对象在ARRAY中位序3|| ” )这样通过ID可以取得 “对象在ARRAY中位序1|| 对象在ARRAY中位序2|| 对象在ARRAY中位序3|| ”
再split, 到array中取你要的对象。
key 放 对象
value 放 id
这样满足楼主的需要,不会被覆盖了。
兄弟你通过 vaule 去找 id???你好猛啊
//待保存的对象类。
}
public class Collector{
private Map<Integer,Object> buff = new HashMap<Integer,Object>();
private List<MyObject> createList(){
return new LinkedList<MyObject>();
}
public void put(Integer id,MyObject obj){
Object o = buff.get(id);
if(o==null){
buff.put(id,obj);
}else if(o instanceof List)[
((List)o).add(obj);
}else{
List<MyObject> list = createList();
list.add((MyObject)o);
list.add(obj);
buff.put(id,list);
}
}
public List<MyObject> getMyObjectList(int id){
Object o = buff.get(id);
if(o==null)return null;
else if(o instanceof List){
return (List)o;
}else{
List<MyObject> list = new ArrayList<MyObject>(1);
list.add((MyObject)o);
return list;
}
}
}
List可以换成Set,这样就不会有重复的对象保存到Set当中去。