LoginSignup
13
14

More than 5 years have passed since last update.

Pythonの配列処理をJavaで書く

Last updated at Posted at 2014-01-14

最後尾の要素を持ってくる

Pythonでは以下のコードで書けるものが

a = [1,2,3,4,5]
a[-1]

javaならこうなる.

int[] a = {1,2,3,4,5};
a[a.length - 1];

配列の結合

Pythonでは以下のコードで書けるものが

a = [1,2,3,4,5]
b = [6,7,8]
concat = a + b

javaならこうなる.

int[] a = {1,2,3,4,5};
int[] b = {6,7,8};
int[] concat = new int[a.length + b.length];

int pos = 0;
System.arraycopy(a, 0, concat, pos, a.length);
pos += a.length;
System.arraycopy(b, 0, concat, pos, b.length);

System.arraycopyの引数の順番と役割を覚えておこう.

部分配列の作成

Pythonでは以下のコードで書けるものが

a = [1,2,3,4,5]
a[1:]

javaならこうなる.

import java.util.Arrays;

int[] a = {1,2,3,4,5};
int[] b1 = Arrays.copyOfRange(a, 1, a.length);

map関数

Pythonのmap関数は配列の各要素に適用したい処理をループを使わずに実装できる。コード数が節約でき、コーディングスタンダードとすれば可読性も上がる。ただ、処理スピードに関しては、リスト内包表記の方が早いという報告があるので注意すること。また、itertools.imapを使える状況ならそちらを使う方が高速である場合が多い。ただ、ここでは、map関数をjavaで書くとどうなるのかという点に焦点を当てる.

Pythonでは以下のコードで書けるものが

a = [1,2,3,4,5]
map(lamba x: x+1, a)

javaならこうなる。

import java.util.Arrays;
import com.apache.commons.lang3.ArrayUtils;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;

int[] a = {1,2,3,4,5};
Collection<Integer> b = Collections2.transform(
        Arrays.asList(ArraysUtils.toObject(a)),
        new Function<Integer, Integer>() {
            @Override
            public Integer apply (Integer x) { 
                return x+1;
            }
        }
    );

Collectionになってしまうのはご愛嬌。なお、この表現を使うには、

  • commons-lang.jar
  • guava.jar

が必要であり、それぞれ以下から取得できる.

※apache commons langのArrayUtilsは、guava中の他のパッケージにある機能で置き換えられる可能性が高い(まだ不勉強なので、今回はcommons-langを使う.)。

簡単にコード中の処理について解説する.

Collection<Integer> b = Collections2.transform(
    …
    );

Collections2.transform()関数は、map関数に当たる.第一引数で与えられた配列の各要素に対して、Functionの処理を適用する.

        Arrays.asList(ArraysUtils.toObject(a)),

この部分は、commons-langを使って、intの配列をprimitive型からobject型に変換した後に、List化している.

        new Function<Integer, Integer>() {
            …
        }

Functionのgeneric表現は、左が返り値、右が引数・配列の要素を表し,applyの返り値、引数はこれに対応していなければいけない.pythonのlambda関数に当たる.

これでは、for文を回した方が早いような気がするが、より複雑な処理をしたくなる(例えば、オブジェクトの中の特定のフィールド値に処理をかけ、その結果配列を得たい場合)と初めてこの表現が生きてくる.

おわりに

意外とjavaでも簡単に書けるものも多い.これからも気づいたらこのページに互換のコードをアップしていこうと思う.

両方の言語の動作確認のために

Pythonはインタラクティブシェルが存在するが、Javaには存在しない.ただ、この程度のサンプルを試すためにクラスの記述をいちいちするのも面倒だ.そのようなニーズのために,BeanShellというプログラムが公開されており,Javaの文法に基づいたスクリプティングができるツールが提供されている.Macには以下のサイトからインストールパッケージが提供されている.

13
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
14