私はintの配列を持っています。各要素に 1 を追加する必要があります。特定の定数を各要素に追加する、つまり明示的なループなしで、最短かつ最も一般的な方法は何ですか? オンラインで調べたところ、配列への要素の追加(つまり、連結) に関するページが増え続けています。
各要素をループして定数を追加するよりもエレガントなものはありませんか? ある種の標準ライブラリメソッドはありますか?
さらに言えば、明示的なループなしで 2 つの配列を加算 (つまり、行列の加算) するにはどうすればよいでしょうか?
上記の 2 つのケースをFunctional Javaで記述する方法を次に示します。
1. 各要素に 1 を追加します。
これは関数型プログラミング ライブラリであるため、変更操作は提供しません。ただし、それらは自分で簡単に追加できます。
public static <A> void transform(Array<A> xs, F<A, A> f) {
for(int i = 0; i < xs.length(); i++) {
xs.set(i, f.f(xs.get(i)));
}
}
使用する:
transform(yourArray, Integers.add.f(1));
2. 2 つの行列を追加します。
とを両方の型の 2 つの行列としxssます。次に、それらを追加できます:yssArray<Array<Integer>>
xss.zip(yss).map(new F<P2<Array<Integer>, Array<Integer>>, Array<Integer>>() {
public Array<Integer> f(P2<Array<Integer>, Array<Integer>> p) {
Array<Integer> xs = p._1();
Array<Integer> ys = p._2();
return xs.zip(ys).map(new F<P2<Integer, Integer>, Integer>() {
public Integer f(P2<Integer, Integer> q) {
return q._1() + q._2();
}
});
}
});
これは必要以上に冗長に感じるかもしれません。これは、Java がラムダ式をまだサポートしていないためです。それまでの間、 IDE はそのような手法をより親しみやすいものにするのに役立ちます。
変更不可能な結果が問題なく、配列の使用に固執していない場合は、かわいいトリックを使用して、可能な限り最後の瞬間まで加算を遅らせることができます。しかし、結果配列全体にアクセスする必要があるとすぐに、パフォーマンス上のメリットが失われ、コードが必要以上に複雑になります。
public class OffsetArrayList extends AbstractList< Integer > {
private final List< Integer > liUnderlying;
private final int iOffset;
public OffsetArrayList( int iOffset, liUnderlying ) {
this.iOffset = iOffset;
this.liUnderlying = liUnderlying;
}
@Override
public Integer get( int iIndex ) {
return liUnderlying.get( iIndex ) + iOffset;
}
@Override
public Integer set( int iIndex, Integer iNewValue ) {
return liUnderlying.set( iIndex, iNewValue - iOffset ) + iOffset;
}
// etc.
}
// create new array
int[] aiInput = new int[] { 23, 98, -45 };
// two object allocations, but no new array created and no additions performed
OffsetArrayList alPlusOne = new OffsetArrayList( 1, Arrays.asList( aiInput ) );
// one addition performed; constant time
assert( alPlusOne.get( 0 ) == 24 );
// benefit murky, as we are adding to the same element repeatedly
for ( int i = 0; i < 1000000; ++i )
assert( alPlusOne.get( 2 ) == -44 );
// benefit lost, input destroyed
int[] aiOutput = alPlusOne.toArray( aiInput );