วิธีสร้างอาร์เรย์อาร์เรย์ใน Java


115

สมมุติว่าฉันมีวัตถุอาร์เรย์ 5 สาย:

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

และฉันต้องการให้อ็อบเจ็กต์อาร์เรย์อื่นมีอ็อบเจ็กต์อาร์เรย์สตริง 5 ตัว ฉันต้องทำอย่างไร? ฉันสามารถใส่ในอาร์เรย์อื่นได้หรือไม่?


43
คำถาม Noob อาจเป็นเรื่องจริงจัง ในความเป็นจริงพวกเขามักจะ :-)
TJ Crowder

3
คำถามที่ตรงประเด็นและคำตอบไม่ชัดเจนสำหรับผู้ที่รู้ว่าการจัดตำแหน่งหน่วยความจำเสร็จสิ้นอย่างไร +1
เบ็ญ

คำตอบ:


153

แบบนี้:

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

หรือ

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

(ไวยากรณ์หลังสามารถใช้ในการกำหนดได้นอกเหนือจากที่จุดของการประกาศตัวแปรในขณะที่ไวยากรณ์ที่สั้นกว่าใช้ได้กับการประกาศเท่านั้น)


คุณช่วยอธิบายเพิ่มเติมได้ไหมว่าไวยากรณ์ที่สองทำอะไร มันไม่ชัดเจนสำหรับฉัน
Terence Ponce

4
@Terence: มันทำเช่นเดียวกับครั้งแรก: สร้างอาร์เรย์ของการอ้างอิงอาร์เรย์สตริงเริ่มต้นไปยังค่า array1, array2, array3, array4 และ array5 ซึ่งแต่ละส่วนมีการอ้างอิงอาร์เรย์สตริงในตัวเอง
Jon Skeet

1
คำถามด่วน: ฉันจะทำสิ่งนี้ได้อย่างไรในขณะทำงานหากฉันไม่รู้ว่าจะสร้างวัตถุอาร์เรย์กี่ชิ้น
Terence Ponce

1
@Terence: คุณสามารถยกตัวอย่างที่เฉพาะเจาะจงมากขึ้นได้ไหม? เมื่อคุณระบุค่าเริ่มต้นในเวลาคอมไพล์คุณจะทราบขนาด คุณหมายถึงอะไรเช่นnew String[10][]?
Jon Skeet

ใช่. คล้ายกับคำตอบของปีเตอร์.
Terence Ponce

71

ลอง

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

1
อันนี้ยืดหยุ่นกว่า
hetaoblog

คุณไม่ควรกำหนดขนาดคงที่ในอาร์เรย์ของคุณหรือไม่?
Filip

@Filip ได้รับการแก้ไขเป็น 5 การตั้งค่าระดับถัดไปที่จัดสรรไว้ล่วงหน้า แต่สามารถเปลี่ยนแปลงได้ดังนั้นการตั้งค่าอาจไม่เป็นประโยชน์
Peter Lawrey

8
ฉันจะแทรกข้อมูลลงในอาร์เรย์ได้อย่างไร ถ้าข้อมูลแบบไดนามิก?
Prakhar Mohan Srivastava

1
@PrakharMohanSrivastava คุณสามารถตั้งค่าองค์ประกอบทีละรายการ: arrays[0] = new String[] {"a", "b", "c"}หรือใช้รายการชั่วคราว: <pre> <code> รายการ <สตริง []> myList = ArrayList ใหม่ <> (); myList.add (สตริงใหม่ [] {"a", "b", "c"}); myList.add (สตริงใหม่ [] {"d", "e", "f"}); myList.toArray (อาร์เรย์); </code> </pre>
kntx

26

แม้ว่าจะมีคำตอบที่ยอดเยี่ยมสองคำที่บอกคุณว่าต้องทำอย่างไร แต่ฉันรู้สึกว่าไม่มีคำตอบอื่นหายไป: ในกรณีส่วนใหญ่คุณไม่ควรทำเลย

อาร์เรย์มีความยุ่งยากโดยส่วนใหญ่คุณควรใช้Collection APIมากกว่า

ด้วย Collections คุณสามารถเพิ่มและลบองค์ประกอบและมี Collections พิเศษสำหรับฟังก์ชันการทำงานที่แตกต่างกัน (การค้นหาตามดัชนีการเรียงลำดับความเป็นเอกลักษณ์การเข้าถึง FIFO การทำงานพร้อมกัน ฯลฯ )

แม้ว่าจะเป็นเรื่องดีและสำคัญที่ต้องรู้เกี่ยวกับ Arrays และการใช้งาน แต่ในกรณีส่วนใหญ่การใช้ Collections ทำให้ API สามารถจัดการได้ง่ายขึ้น (ซึ่งเป็นสาเหตุที่ไลบรารีใหม่ ๆ เช่นGoogle Guavaแทบจะไม่ใช้ Arrays เลย)

ดังนั้นสำหรับสถานการณ์ของคุณฉันต้องการ 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 [] [] เล็กน้อย แต่อนุญาตให้ดำเนินการได้มากขึ้นเช่นการต่อข้อมูล อย่างไรก็ตามวิธีแก้ปัญหาของคุณไม่แน่ใจว่าขนาดของข้อมูลอาจเป็นปัญหาได้

1
@Benj หากจำเป็นคุณสามารถเขียนตัวตกแต่งรายการที่ยอมรับเฉพาะบางรายการเท่านั้น
Sean Patrick Floyd

แน่นอนนักตกแต่ง / เครื่องห่อเป็นวิธีที่ดีในการสร้างความสอดคล้องกัน ดังนั้นวิธีที่เราพูดถึงจึงซับซ้อนกว่าอาร์เรย์ธรรมดา สิ่งที่ฉันทำคือคลาสยูทิลิตี้ขนาดเล็ก Array2D <T> ซึ่งรวมวิธีการพื้นฐานบางอย่างเช่น exixts (... ) เป็นต้นฉันโพสต์ไว้ด้านล่าง

6

มีคลาสที่ฉันพูดถึงในความคิดเห็นที่เรามีกับฌอนแพทริคฟลอยด์: ฉันทำด้วยการใช้งานที่แปลกประหลาดซึ่งต้องใช้ 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");
}

4
+1 สำหรับความพยายามของคุณ แต่: แทนที่จะเริ่มต้นฟิลด์ int ของคุณเป็น -1 และกำหนดใหม่ในตัวสร้างคุณควรทำให้เป็นขั้นสุดท้ายและกำหนดเฉพาะในตัวสร้าง
Sean Patrick Floyd

1
@Sean: ฉันแก้ไขโค้ด (โพสต์ใหม่โดยมี "no-GC buffer" รวมถึงความคิดเห็นที่ชาญฉลาดของคุณ
Benj
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.