2009-07-02 7 views
24

Javaでは、コピーを作成することなく配列を切り捨てる方法はありますか?共通のイディオムはArrays.copyOf(foo, n)です(新しい配列はn要素長です)。代替案があるとは思わないが、よりよいアプローチがあるかどうかは不思議だ。アレイをコピーせずにトランケートしますか?

答えて

19

Javaの配列の長さは、初期化後に変更することはできないため、新しいサイズで強制的にコピーを作成します。実際には、Java配列の長さパラメータはfinalと宣言されているため、一度設定すると変更することはできません。

アレイのサイズを変更する必要がある場合は、ArrayListを使用します。

+1

+1、物事の大きさを操作したり要素を効率的に削除しようとすると、Arraylistsはとてもいいです。 – Brian

0

私はそう信じません。配列は連続したメモリブロックとして割り当てられており、そのブロックの一部を解放する方法はないと想像できません。

0

簡潔に:いいえ、私の知る限りではありません。 Java配列は固定サイズのデータ​​構造です。 「論理的に」サイズを変更する唯一の方法は、新しい配列を作成し、それを新しい配列にコピーすることです。

代わりに、配列をコレクションにラップし、実際に値をコピーせずに論理的に配列の長さを減らすために "size"変数を使用するクラスを実装できます。これはアプローチには限界があります。実用的な場所であると想像できる唯一のケースは、メモリの制約のためにコピーできない大規模な配列を扱う場合です。

配列をコピーするのは、比較的安価です...何百万回も実行している場合を除き、おそらくこれを避けるアルゴリズムを考える必要があり、時間を無駄にしないでください。 "可変長配列"。

もちろん...代わりにArrayListを使うこともできます。はい?

5

私はそれについてもう少し考えていました...ちょうどキックのために、以下のようなものはどうですか?

注:これは単なる「できますか?」です。 Javaハッキングの知的運動。実際にこのアイデアをプロダクションコードで使用しようとする人は、間違いなく続くすべての痛みに値するでしょう。

public class Foo 
{ 
    private static byte[] array = new byte[10]; 

    public static void main(String[] arg) throws Exception 
    { 
     Field field = Unsafe.class.getDeclaredField("theUnsafe"); 
     field.setAccessible(true); 
     Unsafe unsafe = (Unsafe) field.get(null); 
     Field arrayField = Foo.class.getDeclaredField("array"); 
     long ptr = unsafe.staticFieldOffset(arrayField); 
     // doesn't work... there's gotta be a way though! 
     unsafe.reallocateMemory(ptr, 5); 
     System.out.println("New array size is: " + array.length); 
    } 
} 
関連する問題