コマンドラインでGitのタグを付けたり削除したりする方法
タグを付ける
ローカルでタグを付けて、その変更をリモートにpushするという流れになります
git tag {TAGNAME} git push origin {TAGNAME}
リモートのタグを削除する
ローカルでタグを削除して、その変更をリモートにpushするという流れになります
git tag -d {TAGNAME} git push origin :{TAGNAME}
コマンドラインでGitのタグを付けたり削除したりする方法
ローカルでタグを付けて、その変更をリモートにpushするという流れになります
git tag {TAGNAME} git push origin {TAGNAME}
ローカルでタグを削除して、その変更をリモートにpushするという流れになります
git tag -d {TAGNAME} git push origin :{TAGNAME}
JavaでListをリテラルに記述して生成する方法が基本的にないので、
文字列List等を作る際には基本的にArrays#asList
を利用することが多いです。
ただし、Arrays#asList
によってに生成されるクラスはArrayList
という名前ですが、
いわゆるjava.util.ArrayList
とは別物であるということを知っておかなければなりません。
サンプルコードを実行して確認してみます。
■サンプルコード
import java.util.ArrayList; import java.util.Arrays; import java.util.List; List<String> list1 = Arrays.asList("a", "b", "c"); System.out.println("## Arrays#asList"); System.out.println("class: " + list1.getClass()); // list1.add("d"); -> throw java.lang.UnsupportedOperationException // list1.remove(0); -> throw java.lang.UnsupportedOperationException System.out.println("--------------------"); List<String> list2 = new ArrayList<>(); list2.add("a"); list2.add("b"); list2.add("c"); System.out.println("## ArrayList"); System.out.println("class: " + list2.getClass());
■実行結果
## Arrays.asList class: class java.util.Arrays$ArrayList -------------------- ## ArrayList class: class java.util.ArrayList
実行結果からArrays#asList
によって生成されるオブジェクトはjava.util.Arrays$ArrayList
というクラスであることが分かります
かなり省略していますがjava.util.Arrays$ArrayList
は以下のような実装になっています。
addやremove等のメソッドはAbstractListから継承してオーバーライドされていないというのがポイントとなります。
(そのためUnsupportedOperationException
がスローされる状態になっています)
public class Arrays { private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable { private static final long serialVersionUID = -2764017481108945198L; private final E[] a; ArrayList(E[] array) { a = Objects.requireNonNull(array); } @Override public int size() { return a.length; } @Override public Object[] toArray() { return a.clone(); } @Override @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { int size = size(); if (a.length < size) return Arrays.copyOf(this.a, size, (Class<? extends T[]>) a.getClass()); System.arraycopy(this.a, 0, a, 0, size); if (a.length > size) a[size] = null; return a; } @Override public E get(int index) { return a[index]; } @Override public E set(int index, E element) { E oldValue = a[index]; a[index] = element; return oldValue; } @Override public int indexOf(Object o) { E[] a = this.a; if (o == null) { for (int i = 0; i < a.length; i++) if (a[i] == null) return i; } else { for (int i = 0; i < a.length; i++) if (o.equals(a[i])) return i; } return -1; } @Override public boolean contains(Object o) { return indexOf(o) != -1; } @Override public Spliterator<E> spliterator() { return Spliterators.spliterator(a, Spliterator.ORDERED); } @Override public void forEach(Consumer<? super E> action) { Objects.requireNonNull(action); for (E e : a) { action.accept(e); } } } }
以前、JMH
で現在日時取得のベンチマークを取得してみました。
今回は色々な日時オブジェクトのメモリサイズをJOL
で確認してみます
今回の測定対象とするクラスは以下です
java.util.Date
java.util.Calendar
java.time.LocalDateTime
java.time.LocalDate
java.time.LocalTime
以下のサンプルコードを実行してメモリサイズを取得してみました
■サンプルコード
import org.openjdk.jol.info.GraphLayout; public class DateObjSize { private static java.util.Date utilDate = new java.util.Date(); private static java.util.Calendar calendar = java.util.Calendar.getInstance(); private static java.time.LocalDateTime localDateTime = java.time.LocalDateTime.now(); private static java.time.LocalDate localDate = java.time.LocalDate.now(); private static java.time.LocalTime localTime = java.time.LocalTime.now(); public static void main(String[] args) { System.out.println("java.util.Date totalSize(byte) -> " + GraphLayout.parseInstance(utilDate).totalSize()); System.out.println("java.util.Date footprint -> \n" + GraphLayout.parseInstance(utilDate).toFootprint()); System.out.println("-------------"); System.out.println("java.util.Calendar totalSize(byte) -> " + GraphLayout.parseInstance(calendar).totalSize()); System.out.println("java.util.Calendar footprint -> \n" + GraphLayout.parseInstance(calendar).toFootprint()); System.out.println("-------------"); System.out.println("java.time.LocalDateTime totalSize(byte) -> " + GraphLayout.parseInstance(localDateTime).totalSize()); System.out.println("java.time.LocalDateTime footprint -> \n" + GraphLayout.parseInstance(localDateTime).toFootprint()); System.out.println("-------------"); System.out.println("java.time.LocalDate totalSize(byte) -> " + GraphLayout.parseInstance(localDate).totalSize()); System.out.println("java.time.LocalDate footprint -> \n" + GraphLayout.parseInstance(localDate).toFootprint()); System.out.println("-------------"); System.out.println("java.time.LocalTime totalSize(byte) -> " + GraphLayout.parseInstance(localTime).totalSize()); System.out.println("java.time.LocalTime footprint -> \n" + GraphLayout.parseInstance(localTime).toFootprint()); } }
■実行結果
java.util.Date totalSize(byte) -> 24 java.util.Date footprint -> java.util.Date@aec6354d footprint: COUNT AVG SUM DESCRIPTION 1 24 24 java.util.Date 1 24 (total) ------------- java.util.Calendar totalSize(byte) -> 712 java.util.Calendar footprint -> java.util.GregorianCalendar@58d25a40d footprint: COUNT AVG SUM DESCRIPTION 1 40 40 [C 4 58 232 [I 1 96 96 [J 1 40 40 [Z 1 24 24 java.lang.String 1 112 112 java.util.GregorianCalendar 1 16 16 sun.util.calendar.Gregorian 1 96 96 sun.util.calendar.Gregorian$Date 1 56 56 sun.util.calendar.ZoneInfo 12 712 (total) ------------- java.time.LocalDateTime totalSize(byte) -> 72 java.time.LocalDateTime footprint -> java.time.LocalDateTime@1c4af82cd footprint: COUNT AVG SUM DESCRIPTION 1 24 24 java.time.LocalDate 1 24 24 java.time.LocalDateTime 1 24 24 java.time.LocalTime 3 72 (total) ------------- java.time.LocalDate totalSize(byte) -> 24 java.time.LocalDate footprint -> java.time.LocalDate@7de26db8d footprint: COUNT AVG SUM DESCRIPTION 1 24 24 java.time.LocalDate 1 24 (total) ------------- java.time.LocalTime totalSize(byte) -> 24 java.time.LocalTime footprint -> java.time.LocalTime@1175e2dbd footprint: COUNT AVG SUM DESCRIPTION 1 24 24 java.time.LocalTime 1 24 (total)
表にまとめると以下の通りです
クラス | メモリサイズ(byte) |
---|---|
java.util.Date | 24 |
java.util.Calendar (java.util.GregorianCalendar) | 712 |
java.time.LocalDateTime | 72 |
java.time.LocalDate | 24 |
java.time.LocalTime | 24 |
クラスごとに特性があるので良い悪いと一概に言えませんが、Calendarのメモリサイズはかなり大きいことが分かります。
Guavaの21.0がいつの間にかリリースされてました。
Release21 · google/guava Wiki · GitHub
今回からJava8必須になったようです。
色々変更があったようなので簡単に(ごく一部を)試してみます。
pom.xmlに以下を追記します
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>21.0</version> </dependency>
Java標準のOptional(java.util.Optional)との相互変換ができるようになっています。
Optional#toJavaUtil
: GuavaのOptional -> java.util.Optional の変換を行います。Optional#fromJavaUtil
: java.util.Optional -> GuavaのOptional の変換を行います。■サンプルコード
import com.google.common.base.Optional; Optional guavaOpt1 = Optional.of("Some"); // Guava -> Java java.util.Optional javaOpt = guavaOpt1.toJavaUtil(); // Java -> Guava Optional guavaOpt2 = Optional.fromJavaUtil(javaOpt);
Multimap
にforEachメソッドがいくつか追加されています
Multimap#foreach
: Multimap内の(重複keyも含めた)全要素に対する処理を行うことができます。(引数にはkeyとvalueが渡されます)■サンプルコード
import com.google.common.collect.Multimap; import com.google.common.collect.ArrayListMultimap; Multimap<String, String> multiMap = ArrayListMultimap.create(); multiMap.put("key1", "value1"); multiMap.put("key1", "value2"); multiMap.put("key1", "value3"); multiMap.put("key2", "data1"); multiMap.put("key3", "Taro"); // 引数にはkeyとvalueが渡される System.out.println("## Multimap#foreach"); multiMap.forEach((k, v) -> System.out.println(k + ": " + v));
■実行結果
## Multimap#foreach key1: value1 key1: value2 key1: value3 key2: data1 key3: Taro
Multiset
にメソッドがいくつか追加されています
Multiset#foreach
: Multiset内の(重複要素も含めた)全要素に対する処理を行うことができます。Multiset#forEachEntry
: Multiset内の各エントリに対する処理を行うことができます。エントリとして要素とその保持数が引数に渡されますMultiset#size
: Multiset内の(重複要素も含めた)全要素を取得することができます。■サンプルコード
import com.google.common.collect.Multiset; import com.google.common.collect.HashMultiset; import com.google.common.collect.Lists; List<String> words = Lists.newArrayList("hello", "dog", "cat", "red", "hello", "hello", "dog", "blue", "blue"); Multiset<String> wordMultiSet = HashMultiset.create(words); System.out.println("## Multiset#foreach"); wordMultiSet.forEach(e -> System.out.println(e)); System.out.println("\n"); System.out.println("## Multiset#forEachEntry"); wordMultiSet.forEachEntry((e, count) -> System.out.println(e + ":" + count)); System.out.println("\n"); System.out.println("## Multiset#size"); System.out.println("size : " + wordMultiSet.size());
■実行結果
## Multiset#foreach red blue blue cat hello hello hello dog dog ## Multiset#forEachEntry red:1 blue:2 cat:1 hello:3 dog:2 ## Multiset#size size : 9
新しく追加されたクラスです、Stream APIにはない補助的なメソッドを提供してくれています
Streams#zip
: 指定された2つのStream内の要素同士を合成することができます。Streams#concat
: 指定された複数のStreamを結合したStreamを返します。Streams#findLast
: Streamの内の最終要素をjava.util.Optionalで返します。■サンプルコード
import com.google.common.collect.Streams; List<Integer> list1 = Arrays.asList(0, 1, 2, 3, 4, 5); List<Integer> list2 = Arrays.asList(12, 13, 14, 15, 16, 17); List<Integer> zippedList = Streams.zip(list1.stream(), list2.stream(), (i1, i2) -> i1 + i2) .collect(Collectors.toList()); System.out.println("Streams#zip List: " + zippedList); List<Integer> concatList = Streams.concat(list2.stream(), list1.stream()) .collect(Collectors.toList()); System.out.println("Streams#concat List: " + concatList); java.util.Optional<Integer> last = Streams.findLast(list1.stream()); last.ifPresent(val -> System.out.println("list1 last -> " +val));
■実行結果
Streams#zip List: [12, 14, 16, 18, 20, 22] Streams#concat List: [12, 13, 14, 15, 16, 17, 0, 1, 2, 3, 4, 5] list1 last -> 5
前回のエントリでND4J
を利用して、Javaプログラムでの行列の演算を試しました
今回は行列の演算をScalaから実行してみます。
開発はsbtを用います。
build.sbtに以下を追記します
libraryDependencies ++= Seq( "org.nd4j" % "nd4j-native-platform" % "0.7.2", "org.slf4j" % "slf4j-api" % "1.7.22", "ch.qos.logback" % "logback-classic" % "1.1.8" )
行列と行列の足し算です。
■サンプルコード
import org.nd4j.linalg.factory.Nd4j val matrixA = Nd4j.create(Array(1.0, 2.0, 3.0, 4.0), Array(2, 2)) val matrixB = Nd4j.create(Array(11.0, 12.0, 13.0, 14.0), Array(2, 2)) val matrixRet1 = matrixA.add(matrixB) println("Ret1: \n" + matrixRet1)
■実行結果
Ret1: [[12.00, 14.00], [16.00, 18.00]]
行列と行列の引き算です。
■サンプルコード
import org.nd4j.linalg.factory.Nd4j val matrixA = Nd4j.create(Array(1.0, 2.0, 3.0, 4.0), Array(2, 2)) val matrixB = Nd4j.create(Array(11.0, 12.0, 13.0, 14.0), Array(2, 2)) val matrixRet2 = matrixA.sub(matrixB) println("Ret2: \n" + matrixRet2)
■実行結果
Ret2: [[-10.00, -10.00], [-10.00, -10.00]]
行列をスカラー倍します。
■サンプルコード
import org.nd4j.linalg.factory.Nd4j val matrixA = Nd4j.create(Array(1.0, 2.0, 3.0, 4.0), Array(2, 2)) val matrixRet3 = matrixA.mul(3) println("Ret3: \n" + matrixRet3)
■実行結果
Ret3: [[3.00, 6.00], [9.00, 12.00]]
行列と行列のかけ算です
■サンプルコード
import org.nd4j.linalg.factory.Nd4j val matrixA = Nd4j.create(Array(1.0, 2.0, 3.0, 4.0), Array(2, 2)) val matrixB = Nd4j.create(Array(11.0, 12.0, 13.0, 14.0), Array(2, 2)) val matrixRet4 = matrixA.mmul(matrixB) println("Ret4: \n" + matrixRet4)
■実行結果
Ret4: [[37.00, 40.00], [85.00, 92.00]]
行列と零行列のかけ算です
■サンプルコード
import org.nd4j.linalg.factory.Nd4j val matrixA = Nd4j.create(Array(1.0, 2.0, 3.0, 4.0), Array(2, 2)) val zeroMatrix = Nd4j.zeros(2, 2) val matrixRet5 = matrixA.mmul(zeroMatrix) println("Ret5: \n" + matrixRet5)
■実行結果
[[0.00, 0.00], [0.00, 0.00]]
行列と単位行列のかけ算です
■サンプルコード
import org.nd4j.linalg.factory.Nd4j val matrixA = Nd4j.create(Array(1.0, 2.0, 3.0, 4.0), Array(2, 2)) val identityMatrix = Nd4j.eye(2) val matrixRet6 = matrixA.mmul(identityMatrix) println("Ret6: \n" + matrixRet6)
■実行結果
Ret6: [[1.00, 2.00], [3.00, 4.00]]
対象行列Cの転置行列を求めます
■サンプルコード
import org.nd4j.linalg.factory.Nd4j val matrixC = Nd4j.create(Array(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0), Array(3, 3)) val matrixRet7 = matrixC.transpose() println("Raw Matrix: \n" + matrixC) println("Transposed Matrix: \n" + matrixRet7)
■実行結果
Raw Matrix: [[1.00, 2.00, 3.00], [4.00, 5.00, 6.00], [7.00, 8.00, 9.00]] Transposed Matrix: [[1.00, 4.00, 7.00], [2.00, 5.00, 8.00], [3.00, 6.00, 9.00]]
対象行列Aの逆行列を求めます
■サンプルコード
import org.nd4j.linalg.factory.Nd4j import org.nd4j.linalg.inverse.InvertMatrix val matrixC = Nd4j.create(Array(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0), Array(3, 3)) val matrixRet8 = InvertMatrix.invert(matrixA, false) println("Raw Matrix: \n" + matrixA) println("Invert Matrix: \n" + matrixRet8) // 元の行列×逆行列=単位行列 println("identity Matrix: \n" + matrixA.mmul(matrixRet8))
■実行結果
Raw Matrix: [[1.00, 2.00], [3.00, 4.00]] Invert Matrix: [[-2.00, 1.00], [1.50, -0.50]] identity Matrix: [[1.00, 0.00], [0.00, 1.00]]