替换HashSet内容而不创建新的HashSet对象

时间:2015-09-25 14:31:50

标签: java collections hashset

我必须操作大HashSet对象下的字符串   我想知道是否有可能操纵现有的   HashSet对象没有创建新的HashSet对象

下面是我当前的逻辑,其中,我想避免创建第二个HashSet(set2对象)。

HashSet<String> set1 = new HashSet<String>();
set1.add("AB.12");
set1.add("CD.34");
set1.add("EF.56");
set1.add("GH.78");

HashSet<String> set2 = new HashSet<String>();
for(String data : set1) {
    set2.add(data.substring(0,2));
}

P.S。:设置Set的原因是为了避免重复输入(来自不同来源)。

4 个答案:

答案 0 :(得分:3)

不应更改HashSet中的元素以维护集合的完整性。您可以将它们视为不可变元素。

由于HashSet的顺序未定义或随时间不变,因此无法同时添加和删除元素而不会与新元素发生冲突。

但是,如果您尝试节省内存,可以同时从set1中删除并添加到set2。

Iterator iter = set1.iterator();

while(iter.hasNext()){
    set2.add(iter.next().substring(0, 2));
    iterator.remove();
}

答案 1 :(得分:1)

Java Set不提供有序访问,因此您无法逐个执行替换。

使用List,您可以执行以下操作:

for (int i = 0; i < list.count(); i++) {

    list.set(i, list.get(i).substring(0, 2));
}

请注意,构建新的Set对象不是问题,除非您拥有大量数据集。

另一种选择是使用Stack

final Stack<String> toProcess = new Stack<>();

for (final String i : set1) {

    toProcess.push(i);
}

set1.clear();

while (!toProcess.isEmpty()) {

    set1.add(toProcess.pop().substring(0, 2));
}

答案 2 :(得分:1)

如果你真的在考虑浪费内存,那么你可以这样做:

   HashSet<String> set2 = new HashSet<String>();

   Iterator<String> ite = set1.iterator();
   while(ite.hasNext()){
         String data = ite.next();
         ite.remove(); //look this
        set2.add(data.substring(0,2));
   }

答案 3 :(得分:1)

对您的问题没有完美的解决方案。问题是根据定义Set不允许编制索引。再加上String不可变的事实,修改数据是不可行的。

我认为你应该考虑改变两件事。

  1. 使用允许您替换元素(例如List
  2. 的数据结构

    2。使用可变数据类型,可能创建自己的类作为数据类型元素(正如Victor在评论中建议的那样)。

    这将打破HashSet的内部,因为索引是通过散列元素创建的,如果元素发生变化,它可能会消失。