数据转换

时间:2010-06-10 14:11:46

标签: java arrays object

我的数据由employers列表和workers列表组成。每个人都与另一个人有多对多的关系(所以雇主可以有很多工人,一个工人可以有很多雇主)。

检索(并提供给我)数据的方式如下:每个employer都有一个workers数组。换句话说:

employer n has:
  worker x, worker y etc.

所以我有一堆雇主对象,每个对象都包含一系列工人。

我需要转换这些数据(并且基本上反转了这种关系)。我需要有一堆worker个对象,每个对象都包含一个employers数组。换句话说:

worker x has:
  employer n1, employer n2 etc.

上下文是假设的,所以请不要评论为什么我需要这个或为什么我这样做。我真的只想帮助算法执行这种转换(没有 那么多的数据所以我更喜欢可读性而不是复杂的优化,这降低了复杂性)。 (哦,我正在使用Java,但伪代码会很好)。

2 个答案:

答案 0 :(得分:4)

你想要一个Map<Worker,Set<Employer>>,或者来自番石榴的Multimap<Worker,Employer>

在伪代码中:

initialize employerMap(worker => set of employers)
for every employer n do
    for every worker x in n.workers do
         employerMap[x].add(n)

基本上Worker可以映射到多个Employer,所以你要么:

  • 有一个Map<Worker,Set<Employer>>
    • Map中的每个键只能包含一个值,因此本例中的值为值Set
  • 有一个Multimap<Worker,Employer>
    • Multimap可以将密钥映射到多个值

实施例

这是一个做映射的例子。请注意,绝对不建议将此类数据存储在Object[][] arr中,并且仅用作示例的一部分。专注于实际的映射部分。

import java.util.*;
public class MultiMapExample {
    public static void main(String[] args) {
        Object[][] arr = {
            { "IBM",    new String[] { "Joe", "Jack", "Carol"   }},
            { "MS",     new String[] { "Jack", "Andy", "Carol" }},
            { "Google", new String[] { "Bob", "Alice", "Carol"  }},
        };
        Map<String,Set<String>> employerMap =
            new HashMap<String,Set<String>>();

        for (Object[] data : arr) {
            String employer = (String) data[0];
            String[] workers = (String[]) data[1];
            for (String worker : workers) {
                Set<String> employers = employerMap.get(worker);
                if (employers == null) {
                    employerMap.put(worker, employers = new HashSet<String>());
                }
                employers.add(employer);
            }
        }

        for (String worker : employerMap.keySet()) {
            System.out.println(worker + " works for " + employerMap.get(worker));
        }
    }
}

此打印(订单可能有所不同):

Alice works for [Google]
Jack works for [IBM, MS]
Bob works for [Google]
Andy works for [MS]
Carol works for [IBM, Google, MS]
Joe works for [IBM]

我建议将数据保存在这样的Map中,但如果由于某种原因必须将员工列表转换为数组,则可以使用Collection.toArray(T[])

但是,您通常应该更喜欢List和其他Java Collections Framework类到数组。


实施equalshashCode

上面的示例使用String来简化。您可能应该使用实际的WorkerEmployer类型,这是一件好事。但是,您必须确保他们正确实施equalshashCode

另见

  • Effective Java 2nd Edition
    • 第8项:在覆盖等于
    • 时遵守一般合同
    • 第9项:覆盖等于
    • 时,始终覆盖哈希码

API链接

相关问题

equals/hashCode组合:

equals vs ==上:

答案 1 :(得分:3)

不是特定于java的,但这是方法:

  • 制作<Worker, Set<Employer>>
  • 字典
  • 遍历每个雇主的所有工人,
  • 对于每个工人,将当前雇主添加到Dict[Worker]

您需要在第一次找到每个工作人员时添加一个检查来创建该集。