Java 处理来自2个贴图的数据以创建第3个贴图 map1=。。。; map2=。。。;

Java 处理来自2个贴图的数据以创建第3个贴图 map1=。。。; map2=。。。;,java,dictionary,hashmap,java-8,Java,Dictionary,Hashmap,Java 8,myStruct有两个字段:时间戳和数字 我需要用map1和map2中的键创建一个新的map3。对于每个键,每次map1和map2的时间戳匹配时,我都需要在mystrct列表中添加一个新条目。该数字应等于map1的数字除以MAP2的数字 例如,如果它们每个都有一个条目: Map<String, List<myStruct>> map1 = ...; Map<String, List<myStruct>> map2 = ...; Map-ma

myStruct有两个字段:时间戳和数字

我需要用map1和map2中的键创建一个新的map3。对于每个键,每次map1和map2的时间戳匹配时,我都需要在mystrct列表中添加一个新条目。该数字应等于map1的数字除以MAP2的数字

例如,如果它们每个都有一个条目:

Map<String, List<myStruct>> map1 = ...;  
Map<String, List<myStruct>> map2 = ...; 
Map-map1=<“Cat”,<,>;
地图地图2=<“猫”,<,>;
然后

map3=<“猫”<,>;
因为对于下午1点:10/5=2,下午2点:6/2=3,下午3点:8/1=8

我已经尝试过使用lambda函数,但是我不能想出任何好的和有效的方法


我现在做的是迭代map1中的每个条目,然后迭代myStructs的每个时间戳-将其与map2中的一个进行比较,如果时间戳相等,则将结果添加到Map3中。我想找出一个更有效的解决办法

您可以这样做:

这是我的struct类,时间戳作为字符串字段(不知道实际示例中使用的是哪种数据类型,这仅供参考)

和测试等级:

public class Mystruct 
{
    private String timeStamp;
    private int number;

    public Mystruct(String timeStamp,int number) 
    {
        this.timeStamp=timeStamp;
        this.number=number;
    }

    public Mystruct() {
        // TODO Auto-generated constructor stub
    }

    public String getTimeStamp() {
        return timeStamp;
    }
    public void setTimeStamp(String timeStamp) {
        this.timeStamp = timeStamp;
    }
    public int getNumber() {
        return number;
    }
    public void setNumber(int number) {
        this.number = number;
    }

    @Override
    public String toString() {
        return "Mystruct [timeStamp=" + timeStamp + ", number=" + number + "]";
    }

}
import java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
公开课考试{
公共静态void main(字符串[]args){
Map map1=新的HashMap();
Map map2=新的HashMap();
List list1=新的ArrayList();
List list2=新的ArrayList();
Mystruct struct1=新的Mystruct(“下午1点”,10);
Mystruct struct2=新的Mystruct(“2PM”,6);
Mystruct struct3=新的Mystruct(“下午3点”,8);
列表1.添加(结构1);
列表1.添加(结构2);
列表1.添加(结构3);
Mystruct struct4=新的Mystruct(“下午1点”,5);
Mystruct struct5=新的Mystruct(“2PM”,2);
Mystruct struct6=新的Mystruct(“下午3点”,1);
列表2.添加(结构4);
列表2.添加(结构5);
列表2.添加(结构6);
map1.put(“Cat”,列表1);
map2.put(“Cat”,列表2);
List list3=null;
List list4=null;
Map map3=新的HashMap();
for(字符串键:map1.keySet())
{
if(map2.get(key)!=null)
{
list3=map1.get(key);
list4=map2.get(键);
List structList=新建ArrayList();
for(Mystruct outerStruct:list3)
{
for(Mystruct innerStruct:list4)
{
if(outerStruct.getTimeStamp().equals(innerStruct.getTimeStamp()))
{
Mystruct structToStore=new Mystruct();
setTimeStamp(outerStruct.getTimeStamp());
setNumber(outerStruct.getNumber()/innerStruct.getNumber());
structList.add(structToStore);
}
}
}
map3.put(键,结构列表);
}
}
System.out.println(map3.toString());
}
}
输出:

{Cat=[Mystruct[timeStamp=1PM,number=2],Mystruct[timeStamp=2PM, number=3],Mystruct[timeStamp=3PM,number=8]}


您可以在
map1
的条目上循环,然后通过流式处理map的值来进行除法

检查下面的代码

短代码
tmp
是生成的
列表

长代码
publicstaticvoidmain(字符串[]args){
Map map1=新的HashMap();
Map map2=新的HashMap();
myStruct one=新的myStruct(“下午1点”,10);
myStruct two=新的myStruct(“下午1点”,5);
myStruct thr=新的myStruct(“下午2点”,6);
myStruct fou=新myStruct(“下午2点”,2);
myStruct fiv=新myStruct(“下午3点”,8);
myStruct六=新myStruct(“下午3点”,1);
map1.put(“Cat”,Arrays.asList(one,thr,fiv));
map2.put(“Cat”,Arrays.asList(二,四,六));
Map map3=新的HashMap(map1);
列出tmp;
对于(Map.Entry e:map1.entrySet()){
tmp=e.getValue()
.stream()
.map(struct->newmystruct(struct.time,map2.get(e.getKey())
.stream()
.filter(x->x.time.equals(结构时间))
.mapToInt(x->struct.number/x.number)
.findFirst().getAsInt())
.collect(Collectors.toList());
map3.put(e.getKey(),tmp);
}
System.out.println(map3);//{Cat=[,]}
}

这里有两个嵌套操作:合并地图和合并包含的列表。首先,我认为试图在一个代码块中表达整个操作将变得非常不可读。其次,这些
列表
的合并成本非常高,特别是当它们往往很大时。因此,应该首先将其中一个列表转换为
映射
(假设
字符串
是时间戳值的类型),以便进行有效的查找。在该映射上,将另一个列表与该映射合并到结果列表可以表示为

public static void main(String[] args) {
    Map<String, List<myStruct>> map1 = new HashMap<>();
    Map<String, List<myStruct>> map2 = new HashMap<>();

    myStruct one = new myStruct("1pm", 10);
    myStruct two = new myStruct("1pm", 5);
    myStruct thr = new myStruct("2pm", 6);
    myStruct fou = new myStruct("2pm", 2);
    myStruct fiv = new myStruct("3pm", 8);
    myStruct six = new myStruct("3pm", 1);

    map1.put("Cat", Arrays.asList(one, thr, fiv));
    map2.put("Cat", Arrays.asList(two, fou, six));

    Map<String, List<myStruct>> map3 = new HashMap<>(map1);

    List<myStruct> tmp;

    for (Map.Entry<String, List<myStruct>> e : map1.entrySet()) {
         tmp = e.getValue()
                .stream()
                .map(struct -> new myStruct(struct.time, map2.get(e.getKey())
                                                                   .stream()
                                                                   .filter(x -> x.time.equals(struct.time))
                                                                   .mapToInt(x -> struct.number / x.number)
                                                                   .findFirst().getAsInt()))
                .collect(Collectors.toList());

         map3.put(e.getKey(), tmp);
    }

    System.out.println(map3); // {Cat=[<1pm, 2>, <2pm, 3>, <3pm, 8>]}
}
静态列表组合(列表、地图){
return list.stream()
.地图(a->{
整数b=map.get(a.getTimeStamp());
返回b==null?null:newmystruct(a.getTimeStamp(),a.getNumber()/b);
})
.filter(对象::非空)
.collect(Collectors.toList());
}
此实现关注其他映射中不存在的时间戳。如果始终存在相应的条目,则该方法可以简化为

static List<myStruct> combine(List<myStruct> list, Map<String,Integer> map) {
    return list.stream()
        .map(a -> {
            Integer b=map.get(a.getTimeStamp());
            return b==null? null: new myStruct(a.getTimeStamp(), a.getNumber()/b);
        })
        .filter(Objects::nonNull)
        .collect(Collectors.toList());
}
静态列表组合简化(列表、映射){
return list.stream()
.map(a->newmystruct(a.getTimeStamp(),map.get(a.getTimeStamp())/a.getNumber())
.收集
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test {
    public static void main(String[] args) {
        Map<String, List<Mystruct>> map1 = new HashMap<String, List<Mystruct>>();
        Map<String, List<Mystruct>> map2 = new HashMap<String, List<Mystruct>>();

        List<Mystruct> list1 = new ArrayList<Mystruct>();
        List<Mystruct> list2 = new ArrayList<Mystruct>();

        Mystruct struct1 = new Mystruct("1PM", 10);
        Mystruct struct2 = new Mystruct("2PM", 6);
        Mystruct struct3 = new Mystruct("3PM", 8);
        list1.add(struct1);
        list1.add(struct2);
        list1.add(struct3);

        Mystruct struct4 = new Mystruct("1PM", 5);
        Mystruct struct5 = new Mystruct("2PM", 2);
        Mystruct struct6 = new Mystruct("3PM", 1);
        list2.add(struct4);
        list2.add(struct5);
        list2.add(struct6);

        map1.put("Cat", list1);
        map2.put("Cat", list2);

        List<Mystruct> list3 = null;
        List<Mystruct> list4 = null;

        Map<String, List<Mystruct>> map3 = new HashMap<String, List<Mystruct>>();
        for (String key : map1.keySet()) 
        {
            if(map2.get(key)!=null)
            {
                list3=map1.get(key);
                list4=map2.get(key);

                List<Mystruct> structList = new ArrayList<Mystruct>();

                for(Mystruct outerStruct:list3)
                {
                    for(Mystruct innerStruct:list4)
                    {
                        if(outerStruct.getTimeStamp().equals(innerStruct.getTimeStamp()))
                        {
                            Mystruct structToStore=new Mystruct();
                            structToStore.setTimeStamp(outerStruct.getTimeStamp());
                            structToStore.setNumber(outerStruct.getNumber()/innerStruct.getNumber());
                            structList.add(structToStore);
                        }

                    }
                }
                map3.put(key, structList);
            }
        }

        System.out.println(map3.toString());

    }

}
 tmp = e.getValue()
        .stream()
        .map(struct -> new myStruct(struct.time, map2.get(e.getKey())
                                                           .stream()
                                                           .filter(x -> x.time.equals(struct.time))
                                                           .mapToInt(x -> struct.number / x.number)
                                                           .findFirst().getAsInt()))
        .collect(Collectors.toList());
public static void main(String[] args) {
    Map<String, List<myStruct>> map1 = new HashMap<>();
    Map<String, List<myStruct>> map2 = new HashMap<>();

    myStruct one = new myStruct("1pm", 10);
    myStruct two = new myStruct("1pm", 5);
    myStruct thr = new myStruct("2pm", 6);
    myStruct fou = new myStruct("2pm", 2);
    myStruct fiv = new myStruct("3pm", 8);
    myStruct six = new myStruct("3pm", 1);

    map1.put("Cat", Arrays.asList(one, thr, fiv));
    map2.put("Cat", Arrays.asList(two, fou, six));

    Map<String, List<myStruct>> map3 = new HashMap<>(map1);

    List<myStruct> tmp;

    for (Map.Entry<String, List<myStruct>> e : map1.entrySet()) {
         tmp = e.getValue()
                .stream()
                .map(struct -> new myStruct(struct.time, map2.get(e.getKey())
                                                                   .stream()
                                                                   .filter(x -> x.time.equals(struct.time))
                                                                   .mapToInt(x -> struct.number / x.number)
                                                                   .findFirst().getAsInt()))
                .collect(Collectors.toList());

         map3.put(e.getKey(), tmp);
    }

    System.out.println(map3); // {Cat=[<1pm, 2>, <2pm, 3>, <3pm, 8>]}
}
static List<myStruct> combine(List<myStruct> list, Map<String,Integer> map) {
    return list.stream()
        .map(a -> {
            Integer b=map.get(a.getTimeStamp());
            return b==null? null: new myStruct(a.getTimeStamp(), a.getNumber()/b);
        })
        .filter(Objects::nonNull)
        .collect(Collectors.toList());
}
static List<myStruct> combineSimplified(List<myStruct> list, Map<String,Integer> map) {
    return list.stream()
        .map(a -> new myStruct(a.getTimeStamp(), map.get(a.getTimeStamp())/a.getNumber()))
        .collect(Collectors.toList());
}
// preparation step
Map<String, Map<String,Integer>> prep=map1.entrySet().stream()
    .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().stream()
        .collect(Collectors.toMap(myStruct::getTimeStamp, myStruct::getNumber))));

// final processing
Map<String, List<myStruct>> result = map2.entrySet().stream()
    .collect(Collectors.toMap(Map.Entry::getKey,
        e -> combine(e.getValue(), prep.get(e.getKey()))));