u-ryo's blog

various information for coding...

ZipOutputStream in Java

| Comments

Javaで複数filesをまとめてzipにして出力する(=downloadさせる)必要があり、 何かlibraryないかなーと探したところ、あまりなくて。 ということは、標準的な手法でもさほど手間はかからないということですね。 確かに、new ZipOutputStream(response.getOutputStream())してから new ZipEntry("file/name")してzos.putNextEntry(entry)して zos.write(...)していけばいいだけですもんね。 Zipファイルによりますと、 new ZipOutputStream(new BufferedOutputStream(...))というように new BufferedOutputStream()でくくった方が3.6倍速い(110ms→30ms)とのこと。 ホント?!

Downloading a File on Angular

| Comments

JHipsterのAngularでfileをdownloadするUIを作っていました。 AタグlinkからserverのAPI叩いて、 Content-Disposition: attachment;filename=... と返せば済むだろう、 と思ってたんですが、そういえば認証通さねばなりません。 となると一旦browserで全部受けてblobにしてから返さないとならなさそうです。 認証header自体は、JHipsterならHTTPのinterceptorがあって、 フツーにthis.http.get(...)とかすれば勝手に付けてくれます。 HTTP Headerの付け方は公式documentにある通りです。 Angular 2 download .CSV file click event with authenticationを参考に、 service化しました。 FileSaver.jsを使うと楽そうですけど、 そんなに互換性が重視されるわけではないことと大したcode量ではないことから、 自分で書きました。 最後、window.open(url);だとwindowが上がってきてしまうので、 AngularでCSVをAPIからDLするときに色々したお話にあるように、 裏で自分で<a href="...">作って自分で叩いて自分で消す、 というように書いたら、うまく行きました。

List to Map in Java

| Comments

JavaでListMapにしたかったんですね。 【Java入門】List⇔Map変換でJava8のStreamを使う方法を見ました。 ここは、いいこと書いてあるんですけど能書きが長い、Java8以前の話は不要(at least for me)、広告が多い感じがする、のが...

基本は単純にCollectors.toMap(s->key, s->value)でいけますと。 但し、duplicated keyがあった場合即Exceptionに。

1
2
3
4
5
6
7
8
9
10
11
12
13
jshell> Stream.of("A quick brown fox jumps over the lazy dog.".split(" ")).collect(Collectors.toMap(s->s.length(),s->s)
   ...> )
|  java.lang.IllegalStateException thrown: Duplicate key 5 (attempted merging values quick and brown)
|        at Collectors.duplicateKeyException (Collectors.java:131)
|        at Collectors.lambda$uniqKeysMapAccumulator$1 (Collectors.java:178)
|        at ReduceOps$3ReducingSink.accept (ReduceOps.java:169)
|        at Spliterators$ArraySpliterator.forEachRemaining (Spliterators.java:948)
|        at AbstractPipeline.copyInto (AbstractPipeline.java:484)
|        at AbstractPipeline.wrapAndCopyInto (AbstractPipeline.java:474)
|        at ReduceOps$ReduceOp.evaluateSequential (ReduceOps.java:913)
|        at AbstractPipeline.evaluate (AbstractPipeline.java:234)
|        at ReferencePipeline.collect (ReferencePipeline.java:511)
|        at (#9:1)

なので、Collectors.toMap(s->key, s->value, (s1,s2)->do)のようにduplicated keyがあった場合の処理もlambdaとして第三引数に書けます。 後勝ちの例↓

1
2
jshell> Stream.of("A quick brown fox jumps over the lazy dog.".split(" ")).collect(Collectors.toMap(s->s.length(),s->s,(s1,s2)->s2))
$11 ==> {1=A, 3=the, 4=dog., 5=jumps}

SQLっぽくCollectors.groupingBy(s->key)を使うと、重複valuesはListに込めてくれるので楽です。

1
2
jshell> Stream.of("A quick brown fox jumps over the lazy dog.".split(" ")).collect(Collectors.groupingBy(s->s.length()))
$12 ==> {1=[A], 3=[fox, the], 4=[over, lazy, dog.], 5=[quick, brown, jumps]}

Flatten Lists in a List in Java

| Comments

Javaでlistの中にlistが複数あるものを、 一つのflatなlistにしたい時、どうするのかなー、と。 Java 8 で ruby の flattenに書いてありました。

1
2
jshell> List.of(List.of("a","b","c"),List.of("d","e"),List.of("f","g")).stream().flatMap(Collection::stream).collect(Collectors.toList())
$7 ==> [a, b, c, d, e, f, g]

flatMap(Collection::stream)がキモですね。 こんなの思い付かないですよ。