【问题标题】:Java create Multidimensional Array from ArrayJava从数组创建多维数组
【发布时间】:2017-03-23 14:05:50
【问题描述】:

我有一个数组Object[],其元素如下:

Foo A
Foo B
Foo C
notFoo A
notFoo B
notFoo C

我想以此创建一个多维数组:

Object[0][] = {Foo A, Foo B, Foo C}
Object[1][] = {notFoo A, notFoo B, notFoo C}

因此,如果此数组中的元素在其第一个标记(例如 Foo)中具有在存储在另一个索引中之前未出现的名称。

所以第一个标记表示“元素套件”,这导致数组中的另一个索引。

有什么办法吗?

编辑:元素是字符串类型。

【问题讨论】:

  • 你可以使用 Map, List> 来映射它们然后你可以获得你输入的类型的列表,如果它不存在,你创建一,然后将值添加到列表中。 (请注意,名称“A”、“B”和“C”是不存在的,只是变量名称。)
  • 我同意使用 Map> 等地图,然后在出现新条目时加载并添加到列表中
  • @Hendrik 记得每个人都喜欢找到有答案的问题 :)

标签: java arrays multidimensional-array


【解决方案1】:

你可以做类似的事情

Map<Object.class, List<Object>>

Map<identifier, List<entries>>

然后在添加到地图时,只需检查地图中是否存在 Object.class,如果它确实获取列表并插入对象,否则在地图中插入一个新条目并将对象添加到列表中。请注意,此解决方案支持列表上的任何键和任何值类型,只要它不是原始类型(即使用原始类型的包装器)

额外的

使用数组意味着你从一开始就知道数组的长度,对于没有定义数组/列表长度的问题,最好使用 List/Map 等数据结构

在评论中指定的 Util 类

这个类包含一个私有地图,一种向地图添加值的方法,以及一种获取地图的方法,或者地图的二维数组版本。

public class UtilClass {

    private Map<Object, List<Object>> map = new HashMap<>();

    public void addMapEntry(Object key, Object data){
        List<Object> list = new ArrayList<>();
        if(map.containsKey(key)) {
            list = map.get(key);
        }
        list.add(data);
        map.put(key, list);
    }

    public Object[][] getMapAs2dArray(){
        Object[][] array = new Object[map.keySet().size()][];
        int index = 0;
        for(Object key : map.keySet()){
            array[index] = map.get(key).toArray();
            index++;
        }
        return array;
    }

    public Map<Object, List<Object>> getMap() {
        return map;
    }
}

上面测试代码的主要方法

public static void main(String[] args){

    UtilClass test = new UtilClass();

    for(int i = 0; i < 10; i++){
        test.addMapEntry("foo", "foo"+i);
        test.addMapEntry("bar", "bar"+i);
    }

    for(Object key : test.getMap().keySet()){
        System.out.println("Printing map");
        System.out.println(key + " = " + test.getMap().get(key).toString());
    }

    Object[][] objects = test.getMapAs2dArray();

    System.out.println("printing 2d Array");
    System.out.println(Arrays.deepToString(objects));

    System.out.print("Done");
}

主要测试方法的输出如下

打印地图

bar = [bar0, bar1, bar2, bar3, bar4, bar5, bar6, bar7, bar8, bar9]

打印地图

foo = [foo0, foo1, foo2, foo3, foo4, foo5, foo6, foo7, foo8, foo9]

打印二维数组

[[bar0, bar1, bar2, bar3, bar4, bar5, bar6, bar7, bar8, bar9], [foo0, foo1, foo2, foo3, foo4, foo5, foo6, foo7, foo8, foo9]]

完成

UtilClass 也可以静态定义为

public class UtilClass {

    public static void addMapEntry(Object key, Map<Object, List<Object>> map, Object data){
        List<Object> list = new ArrayList<>();
        if(map.containsKey(key)) {
            list = map.get(key);
        }
        list.add(data);
        map.put(key, list);
    }

    public static  Object[][] getMapAs2dArray(Map<Object, List<Object>> map){
        Object[][] array = new Object[map.keySet().size()][];
        int index = 0;
        for(Object key : map.keySet()){
            array[index] = map.get(key).toArray();
            index++;
        }
        return array;
    }
}

这样可以在不实例化类的情况下访问功能,如果您不希望为包含数据的地图制作包装器,可能会更好

【讨论】:

  • 之后可以转成数组吗?
  • @Hendrik 好吧,如果绝对需要一个数组,您可以访问地图的大小和包含列表以从该 Map.keySet() 返回一组键在地图中 List.size() 返回一个列表的大小,然后只需简单地从大小创建数组并输入值,任何特定原因它必须是一个数组吗?
  • @Hendrik 我现在已经创建了一个对你有用的类,作为一个实用类,将它添加到答案中
  • @Hendrik 完成了课程的格式化和优化,希望这就是您想要的
  • @Hendrik 意识到静态类方法可能更适合这种情况,因此我也在答案中添加了这个
【解决方案2】:

这里有些东西可能有点过头了,但作为示例仍然会很有趣:

public static <T> Map<Class<?>, List<T>> splitValues(T[] objects)
{
    Map<Class<?>, List<T>> values = new HashMap<>();

    for (T object : objects)
    {
        List<T> list = values.computeIfAbsent(object.getClass(), k -> new ArrayList<>());
        list.add(object);
    }

    return values;
}

public static void main(String[] args)
{
    Object[] objects = {
        new Foo(),
        new Foo(),
        new Foo(),
        new Foo(),
        new Integer(6),
        new Integer(4),
        new String("bla1"),
        new String("bla2"),
    };
    Map<Class<?>, List<Object>> map = splitValues(objects);

    System.out.println(map.get(Foo.class).toString());
    System.out.println(map.get(Integer.class).toString());
    System.out.println(map.get(String.class).toString());

    // [org.stackoverflow.Foo@7699a589, org.stackoverflow.Foo@58372a00, org.stackoverflow.Foo@4dd8dc3, org.stackoverflow.Foo@6d03e736]
    // [6, 4]
    // [bla1, bla2]
}

但是,现在我想知道为什么 Class 或 Class 不起作用。

【讨论】:

    猜你喜欢
    • 2014-11-03
    • 1970-01-01
    • 1970-01-01
    • 2019-07-25
    • 2014-09-25
    • 1970-01-01
    • 1970-01-01
    • 2011-07-23
    • 2014-12-10
    相关资源
    最近更新 更多