Java 重复数据消除哈希映射值
我想知道是否有人知道在Java 重复数据消除哈希映射值,java,arraylist,hashmap,deduplication,Java,Arraylist,Hashmap,Deduplication,我想知道是否有人知道在LinkedHashMap中删除重复值的好方法?我有一个LinkedHashMap,其中有一对字符串和列表。我想删除ArrayList中的重复项。这是为了改善一些下游加工 我能想到的唯一一件事是在迭代HashMap时保存处理后的值的日志,然后通过ArrayList检查以前是否遇到过值。这种方法似乎会随着列表的增长而降低性能。是否有方法预处理HashMap以从ArrayList值中删除重复项 来说明…如果我有 String1>List1(a、b、c) String2>List
LinkedHashMap
中删除重复值的好方法?我有一个LinkedHashMap
,其中有一对字符串
和列表
。我想删除ArrayList
中的重复项。这是为了改善一些下游加工
我能想到的唯一一件事是在迭代HashMap
时保存处理后的值的日志,然后通过ArrayList
检查以前是否遇到过值。这种方法似乎会随着列表的增长而降低性能。是否有方法预处理HashMap
以从ArrayList
值中删除重复项
来说明…如果我有
String1>List1(a、b、c)
String2>List2(c、d、e)
我想删除“c”,这样HashMap中的列表中就不会有重复项了。我相信创建第二个HashMap,可以按值排序(字母顺序,数字顺序),然后对排序后的列表进行一次扫描,检查当前节点是否与下一个节点等效,如果是,则删除下一个节点,并保持增量不变,因此它将保持在排序列表的相同索引上
或者,当您添加值时,您可以检查它是否已经包含此值。我假设您需要唯一的元素(包含在列表中),而不是唯一的列表 如果地图的键与其关联列表中的元素之间不需要关联,只需将所有元素单独添加到一个集合中即可 如果将所有列表添加到一个集合中,该集合将包含唯一的列表对象,而不是列表的唯一元素,因此必须单独添加元素 (当然,您可以使用
addAll
简化此操作)使用:
Map uniques=newlinkedhashmap();
对于(Map.Entry:mapWithDups.entrySet()){
对于(值v:entry.getValue()){
uniques.put(v,entry.getKey());
}
}
ListMultimap uniqueLists=Multimaps.invertFrom(Multimaps.forMap(uniques),
ArrayListMultimap.create());
Map uniqueListsMap=(Map)uniqueLists.asMap();//只有在必要的时候
这应该保持值的顺序,并保持它们的唯一性。如果您可以对结果使用
ListMultimap
,您可能可以使用它,否则您可能只需将uniquelist.asMap()
强制转换为Map
(有一些泛型滥用,但有保证的类型安全)。因此,为了澄清。。。你基本上有K,[V1…Vn],你想要所有V都有唯一的值吗
public void add( HashMap<String, List> map, HashMap<Objet, String> listObjects, String key, List values)
{
List uniqueValues= new List();
for( int i = 0; i < values.size(); i++ )
{
if( !listObjects.containsKey( values.get(i) ) )
{
listObjects.put( values.get(i), key );
uniqueValues.add( values.get(i) );
}
}
map.put( key, uniqueValues);
}
public void add(HashMap映射、HashMap列表对象、字符串键、列表值)
{
List uniqueValues=新列表();
对于(int i=0;i
本质上,我们有另一个HashMap来存储列表值,并且在向映射添加列表时删除非唯一值。这还为您提供了了解值出现在哪个列表中的额外好处。根据您的说明,您需要以下内容:
class KeyValue {
public String key;
public Object value;
KeyValue(String key, Object value) {
this.key = key;
this.value = value;
}
public boolean equals(Object o) {
// boilerplate omitted, only use the value field for comparison
}
public int hashCode() {
return value.hashCode();
}
}
public void deduplicate() {
Map<String, List<Object>> items = new HashMap<String, List<Object>>();
Set<KeyValue> kvs = new HashSet<KeyValue>();
for (Map.Entry<String, List<Object>> entry : items.entrySet()) {
String key = entry.getKey();
List<Object> values = entry.getValue();
for (Object value : values) {
kvs.add(new KeyValue(key, value));
}
values.clear();
}
for (KeyValue kv : kvs) {
items.get(kv.key).add(kv.value);
}
}
class键值{
公共字符串密钥;
公共客体价值;
KeyValue(字符串键、对象值){
this.key=key;
这个值=值;
}
公共布尔等于(对象o){
//省略样板,仅使用值字段进行比较
}
公共int hashCode(){
返回值。hashCode();
}
}
公共无效重复数据消除(){
Map items=newhashmap();
Set kvs=new HashSet();
for(Map.Entry:items.entrySet()){
String key=entry.getKey();
列表值=entry.getValue();
用于(对象值:值){
添加(新键值(键,值));
}
value.clear();
}
用于(关键值kv:kvs){
项目。获取(千伏键)。添加(千伏值);
}
}
使用集合将删除重复的值,
KeyValue
允许我们在执行此操作时保留原始哈希键。根据需要添加getter和setter或泛型。这也将修改原始地图和其中的列表。我还认为这方面的性能应该是O(n)。正如其他人所指出的,您可以在添加时检查值,但是,如果您必须在添加后进行检查:
static public void removeDups(Map<String, List<String>> in) {
ArrayList<String> allValues = new ArrayList<String>();
for (List<String> inValue : in.values())
allValues.addAll(inValue);
HashSet<String> uniqueSet = new HashSet<String>(allValues);
for (String unique : uniqueSet)
allValues.remove(unique);
// anything left over was a duplicate
HashSet<String> nonUniqueSet = new HashSet<String>(allValues);
for (List<String> inValue : in.values())
inValue.removeAll(nonUniqueSet);
}
public static void main(String[] args) {
HashMap<String, List<String>> map = new HashMap<String, List<String>>();
map.put("1", new ArrayList(Arrays.asList("a", "b", "c", "a")));
map.put("2", new ArrayList(Arrays.asList("d", "e", "f")));
map.put("3", new ArrayList(Arrays.asList("a", "e")));
System.out.println("Before");
System.out.println(map);
removeDups(map);
System.out.println("After");
System.out.println(map);
}
你有
Map
,你不想允许重复Foo
?据我所知,他想禁止重复List
…但很难说出他的确切意思?我想确保LinkedHashMap中的数组列表中没有重复项。为了清晰起见,我将对问题进行编辑。是否要同时删除每个ArrayList或所有ArrayList的重复数据?只是为了澄清:您希望映射中所有列表的值都是唯一的?因此,如果您有一个mapfoo=>[1,2,2,3],bar=>[2,3,3,4,5]
,那么重复数据消除的结果应该是foo=>[1,2,3],bar=>[4,5]
?既然OP已经澄清了他想要什么,这并不是他想要的。但他想要的是疯狂的。:-)
static public void removeDups(Map<String, List<String>> in) {
ArrayList<String> allValues = new ArrayList<String>();
for (List<String> inValue : in.values())
allValues.addAll(inValue);
HashSet<String> uniqueSet = new HashSet<String>(allValues);
for (String unique : uniqueSet)
allValues.remove(unique);
// anything left over was a duplicate
HashSet<String> nonUniqueSet = new HashSet<String>(allValues);
for (List<String> inValue : in.values())
inValue.removeAll(nonUniqueSet);
}
public static void main(String[] args) {
HashMap<String, List<String>> map = new HashMap<String, List<String>>();
map.put("1", new ArrayList(Arrays.asList("a", "b", "c", "a")));
map.put("2", new ArrayList(Arrays.asList("d", "e", "f")));
map.put("3", new ArrayList(Arrays.asList("a", "e")));
System.out.println("Before");
System.out.println(map);
removeDups(map);
System.out.println("After");
System.out.println(map);
}
Before
{3=[a, e], 2=[d, e, f], 1=[a, b, c, a]}
After
{3=[], 2=[d, f], 1=[b, c]}