【问题标题】:How to make an array of arrays in Java如何在Java中制作数组数组
【发布时间】:2011-06-14 10:40:18
【问题描述】:

假设我有 5 个字符串数组对象:

String[] array1 = new String[];
String[] array2 = new String[];
String[] array3 = new String[];
String[] array4 = new String[];
String[] array5 = new String[];

我希望另一个数组对象包含这 5 个字符串数组对象。我该怎么做?我可以把它放在另一个数组中吗?

【问题讨论】:

  • 新手问题可能很严重。事实上,他们经常如此。 :-)
  • 相关问题,对于谁知道内存对齐是如何完成的,答案并不明显。 +1

标签: java arrays


【解决方案1】:

像这样:

String[][] arrays = { array1, array2, array3, array4, array5 };

String[][] arrays = new String[][] { array1, array2, array3, array4, array5 };

(后一种语法可以用在变量声明点以外的赋值中,而较短的语法只适用于声明。)

【讨论】:

  • 您能否进一步解释第二种语法的作用?我有点不清楚。
  • @Terence:它与第一个相同:它创建一个字符串数组引用数组,初始化为值 array1、array2、array3、array4 和 array5 - 每个本身都是一个字符串数组引用。
  • 快速提问:如果我不知道要创建多少数组对象,我将如何在运行时执行此操作?
  • @Terence:你能举一个更具体的例子吗?当您在编译时指定初始值时,您确实知道大小。你的意思是像new String[10][]这样的东西吗?
  • 是的。类似于彼得的回答。
【解决方案2】:

试试

String[][] arrays = new String[5][];

【讨论】:

  • 这个比较灵活
  • 你不应该在你的数组上定义一个固定的大小吗?
  • @Filip 固定为 5。设置下一个级别会预先分配它们,但这可以更改,因此设置它可能没有用。
  • 如何将数据插入到数组中?如果是动态数据?
  • @PrakharMohanSrivastava 您可以单独设置元素:arrays[0] = new String[] {"a", "b", "c"} 或使用临时列表:
     List<string> myList = new ArrayList(); myList.add(new String[]{"a", "b", "c"}); myList.add(new String[]{"d", "e", "f"}); myList.toArray(数组); </string>
【解决方案3】:

虽然有两个很好的答案告诉你如何去做,但我觉得缺少另一个答案:在大多数情况下你根本不应该这样做。

数组很麻烦,大多数情况下最好使用Collection API

使用 Collections,您可以添加和删除元素,并且有专门的 Collections 用于不同的功能(基于索引的查找、排序、唯一性、FIFO 访问、并发等)。

虽然了解数组及其用法固然很好也很重要,但在大多数情况下,使用集合会使 API 更易于管理(这就是为什么像 Google Guava 这样的新库根本不使用数组的原因)。

因此,对于您的场景,我更喜欢 List of Lists,并且我会使用 Guava 创建它:

List<List<String>> listOfLists = Lists.newArrayList();
listOfLists.add(Lists.newArrayList("abc","def","ghi"));
listOfLists.add(Lists.newArrayList("jkl","mno","pqr"));

【讨论】:

  • 比 String[ ][ ] 稍微复杂一点,但允许更多的操作,例如连接数据。但是,您的解决方案不能确保数据的大小,这可能是个问题。
  • @Benj 如有必要,总是可以编写一个只接受一定数量项目的 List 装饰器。
  • 确切地说,装饰器/包装器是确保连贯性的好方法。因此,我们所说的方式比简单的数组要复杂得多。我所做的是一个小型实用程序类 Array2D,它封装了一些基本方法,例如 exixts(...) 等。我在下面发布了这个。
【解决方案4】:

我在与 Sean Patrick Floyd 的评论中提到了一个类:我做了一个特殊的用途,需要 WeakReference,但您可以通过任何对象轻松更改它。

希望有一天这可以帮助某人:)

import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.NoSuchElementException;
import java.util.Queue;


/**
 *
 * @author leBenj
 */
public class Array2DWeakRefsBuffered<T>
{
    private final WeakReference<T>[][] _array;
    private final Queue<T> _buffer;

    private final int _width;

    private final int _height;

    private final int _bufferSize;

    @SuppressWarnings( "unchecked" )
    public Array2DWeakRefsBuffered( int w , int h , int bufferSize )
    {
        _width = w;
        _height = h;
        _bufferSize = bufferSize;
        _array = new WeakReference[_width][_height];
        _buffer = new LinkedList<T>();
    }

    /**
     * Tests the existence of the encapsulated object
     * /!\ This DOES NOT ensure that the object will be available on next call !
     * @param x
     * @param y
     * @return
     * @throws IndexOutOfBoundsException
     */public boolean exists( int x , int y ) throws IndexOutOfBoundsException
    {
        if( x >= _width || x < 0 )
        {
            throw new IndexOutOfBoundsException( "Index out of bounds (get) : [ x = " + x + "]" );
        }
        if( y >= _height || y < 0 )
        {
            throw new IndexOutOfBoundsException( "Index out of bounds (get) : [ y = " + y + "]" );
        }
        if( _array[x][y] != null )
        {
            T elem = _array[x][y].get();
            if( elem != null )
            {
            return true;
            }
        }
        return false;
    }

    /**
     * Gets the encapsulated object
     * @param x
     * @param y
     * @return
     * @throws IndexOutOfBoundsException
     * @throws NoSuchElementException
     */
    public T get( int x , int y ) throws IndexOutOfBoundsException , NoSuchElementException
    {
        T retour = null;
        if( x >= _width || x < 0 )
        {
            throw new IndexOutOfBoundsException( "Index out of bounds (get) : [ x = " + x + "]" );
        }
        if( y >= _height || y < 0 )
        {
            throw new IndexOutOfBoundsException( "Index out of bounds (get) : [ y = " + y + "]" );
        }
        if( _array[x][y] != null )
        {
            retour = _array[x][y].get();
            if( retour == null )
            {
            throw new NoSuchElementException( "Dereferenced WeakReference element at [ " + x + " ; " + y + "]" );
            }
        }
        else
        {
            throw new NoSuchElementException( "No WeakReference element at [ " + x + " ; " + y + "]" );
        }
        return retour;
    }

    /**
     * Add/replace an object
     * @param o
     * @param x
     * @param y
     * @throws IndexOutOfBoundsException
     */
    public void set( T o , int x , int y ) throws IndexOutOfBoundsException
    {
        if( x >= _width || x < 0 )
        {
            throw new IndexOutOfBoundsException( "Index out of bounds (set) : [ x = " + x + "]" );
        }
        if( y >= _height || y < 0 )
        {
            throw new IndexOutOfBoundsException( "Index out of bounds (set) : [ y = " + y + "]" );
        }
        _array[x][y] = new WeakReference<T>( o );

        // store local "visible" references : avoids deletion, works in FIFO mode
        _buffer.add( o );
        if(_buffer.size() > _bufferSize)
        {
            _buffer.poll();
        }
    }

}

如何使用它的示例:

// a 5x5 array, with at most 10 elements "bufferized" -> the last 10 elements will not be taken by GC process
Array2DWeakRefsBuffered<Image> myArray = new Array2DWeakRefsBuffered<Image>(5,5,10);
Image img = myArray.set(anImage,0,0);
if(myArray.exists(3,3))
{
    System.out.println("Image at 3,3 is still in memory");
}

【讨论】:

  • +1 为您的努力,但是:不要将您的 int 字段初始化为 -1 并在构造函数中重新分配它们,您应该将它们设为最终并在 only 中分配它们构造函数。
  • @Sean :我修改了代码(发布了带有“no-GC buffer”的新代码,包括您的明智评论。
猜你喜欢
  • 2012-04-08
  • 1970-01-01
  • 2015-07-12
  • 2018-11-05
  • 1970-01-01
  • 2017-08-18
  • 1970-01-01
  • 2013-03-15
  • 1970-01-01
相关资源
最近更新 更多