Java関連自分用メモ

2021/01/26: そろそろ増えてきたので、項目ごとを記事ごとに分けようかな

#時間関連

<font color="Red">*Dateを使わない、outdated、下の参照*</font>

```java
	public static Date endYearDate(String dateStr) {
		return DateUtils.parseDate(String.format("%s/12/31", dateStr), "yyyy/MM/dd");
	}

	public static Date startYearDate(String dateStr){
		return DateUtils.parseDate(String.format("%s/01/01", dateStr), "yyyy/MM/dd");
	}

	public static Date startMonthDate(String dateStr) {
		LocalDate localDate = LocalDate.parse(dateStr, DateTimeFormatter.ofPattern("yyyy/MM/dd"));
		return Date.from(localDate.withDayOfMonth(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
	}

	public static Date endMonthDate(String dateStr) {
		LocalDate localDate = LocalDate.parse(dateStr, DateTimeFormatter.ofPattern("yyyy/MM/dd"));
		return Date.from(localDate.withDayOfMonth(localDate.lengthOfMonth()).atStartOfDay(ZoneId.systemDefault()).toInstant());
	}

```

###java.sql.Timestampとjava.sql.Dateはoutdated
使うなら java8 のjava.timeを使う(Instant, LocalDateTime)

```java
Instant now = Instant.now();
Instant instant = myJavaSqlTimestamp.toInstant();

//秒までだけ欲しい場合
LocalDateTime localDateTimeNow = LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS)

```
####参考リンク
https://stackoverflow.com/questions/8929242/compare-date-object-with-a-timestamp-in-java
https://www.baeldung.com/migrating-to-java-8-date-time-api
https://stackoverflow.com/questions/21448500/how-to-remove-milliseconds-from-date-object-format-in-java
InstantとLocalDateTimeの違い
https://stackoverflow.com/questions/32437550/whats-the-difference-between-instant-and-localdatetime
Java 8 Date Time Intro
https://www.baeldung.com/java-8-date-time-intro



##CSVファイル関連
####Controller
```java
@PostMapping(value = "/csv", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseResult insertCsv(@RequestPart("file") MultipartFile file){
       //処理
    }
```
####Service
```java
public List<DTO> convertCsvFileToList(MultipartFile file) throws Exception{
        List<DTO> csvList = new ArrayList<>();
        InputStream is = file.getInputStream();
        InputStreamReader isr = new InputStreamReader(is, "UTF-8");
        BufferedReader br = new BufferedReader(isr);

        String line;
        int cnt = 0;
        while((line = br.readLine()) != null){
        byte[] b = line.getBytes();
        line = new String(b, "UTF-8");
        String[] columns = line.split(",", -1);
        if(cnt != 0){
           //csvのcolumn数
           if(columns.length == 5){
                        String columns0 = columns[0];
                        ...
                        
                }
                cnt++;
            }

        return csvList;
    }
```

####Test(ファイル作成なし)
```java
        String[] header = {"Column1", "Column2", "Col3"};
        String[] data1 = {"A", "1", "あ"};

        String joinedHeader = String.join(",", header);
        String join1 = String.join(",", data1);

        String csv = joinedHeader + "\n" + join1;

        MockMultipartFile file = new MockMultipartFile("file", "test", MediaType.MULTIPART_FORM_DATA_VALUE, csv.getBytes());

        service.convertCsvFileToList(file);

```

## Enum

listの中でEnumのもの存在しているかどうか

```java
EnumSet<MyEnum> set = EnumSet.allOf(MyEnum.class);
boolean contains = list.stream().anyMatch(set::contains);
```

<details><summary>参考link</summary><div>

```java
https://stackoverflow.com/questions/49772441/check-if-list-contains-at-least-one-of-another-enums
```

</div></details>

## Lambda

lambdaのforEachで次のアイテムに行く

```java
public static void main(String[] args) {
    ArrayList<String> stringList = new ArrayList<>();
    stringList.add("a");
    stringList.add("b");
    stringList.add("c");

    stringList.stream().forEach(str -> {
        if (str.equals("b")) return; // これのみスキップされます
        System.out.println(str);
    });
}
```

```java
//これはあくまでも自分独自のメソード扱い
str -> {
    if (str.equals("b")) return;

    System.out.println(str);
}
```
```java
//これもただのloopに過ぎない
stringList.stream().forEach()
```
なので上の動きは細かいコードにするとこんな感じ

```java

public static void main(String[] args) {
    ArrayList<String> stringList = new ArrayList<>();
    stringList.add("a");
    stringList.add("b");
    stringList.add("c");

    for(String s : stringList) {
        lambdaExpressionEquivalent(s);
    }
}

private static void lambdaExpressionEquivalent(String str) {
    if (str.equals("b")) {
        return;
    }

    System.out.println(str);
}

```
<details><summary>参考link</summary>
https://stackoverflow.com/questions/32654929/move-to-next-item-using-java-8-foreach-loop-in-stream
</details>

## List関連
#### Listの中で複数ものが存在しているかどうかをチェック
*List.containsAllもよいが、O(NK)なので、performanceが落ちてしまう、hashsetを使えばperformanceが上がります

```java
HashSet<String>set = new HashSet<>(list);
   if(set.containsAll(Arrays.asList("asd", "efg"))){
   //何かをやる
}
```

####Listから物を削除

```java
ArrayList<String> myList = new ArrayList<>();
myList.add("a");
myList.add("b");
myList.add("c");

Iterator i = myList.iterator();
while(i.hasNext()){
  String str = i.next();
  if(str.equals("b")){
    i.remove();
    break;
  }
}

for(String str : myList){
    System.out.println(str);
}
```

<details><summary>参考link</summary>
1.https://stackoverflow.com/questions/20455654/convenient-method-to-check-if-a-list-contains-multiple-elements
2.https://www.tutorialspoint.com/use-iterator-to-remove-an-element-from-a-collection-in-java#:~:text=An%20element%20can%20be%20removed,the%20exception%20IllegalStateException%20is%20thrown.
<details>


## List\<Map\<String, Object>>関連

```java
List<Map<String, Object>> list;

for (Map<String, Object> map : list) {
    for (Map.Entry<String, Object> entry : map.entrySet()) {
        String key = entry.getKey();
        Object value = entry.getValue();
    }
}

///もしくは
list.forEach(item -> 
      item.forEach((k, v) -> System.out.println(k + ": " + (String)v)
  );
```



##Mybatis関連
DTO

```java
public class DTO {
    //SQLのDBではaddress
    private String address;

    //SQLのDBではcreated_time
    private Timestamp createdTime;
}
```

Mapper

```java
    //DTOの名前とDBの名前をマッピング成功
    @Insert("insert into table(address,created_time)"
            + "values(#{address},#{createdTime})")
    int insertSuccess(DTO dto);

    //addressは取得成功だが、createdTimeはマッピングされずnullになります
    @Select("select * from table")
    List<DTO> getAllFail();

    //こんな風にマッピングさせ、createdTimeの取得が成功します,idは何を書いてもいい
    @Results(id="WriteAnythingHere", value={
            @Result(column="address",property="address"),
            @Result(column="created_time", property="createdTime"))
    })
    @Select("select * from table")
    List<DTO> getAllSuccess();

    //@ResultMapで上記のマッピングIDを使って何度も同じものを書かずに再用できます
    @ResultMap("WriteAnythingHere")
    @SelectProvider(type = Table1Provider.class, method="findAllByCondition")
    List<DTO> findAllByCondition(DTO dto);

    class Table1Provider{
            public  String findAllByCondition(DTO dto){
                return new SQL(){{
                    SELECT("*");
                    FROM("table");
                    if((null != dto.getAddress()) && (0 != dto.getAddress().length())){
                        WHERE("address=#{address}");
                    }
                    ORDER_BY("created_time");
                }}.toString() + " DESC" ;
            }
    };
    
```
####参考リンク
https://qiita.com/yoshikawaa/items/b694361026c3993472af

##Partition関連



##Set関連
新しいsetを古いsetに入れる,setは重複する物がないので、そのまま気にせずaddAllすればok

```java
newStringSet.addAll(oldStringSet);
```


##Streams関連

配列で存在しているかどうか

```java
String[] values = {"AB","BC","CD","AE"};
boolean contains = Arrays.stream(values).anyMatch("s"::equals);
```
primitiveではない方の探し方

```java
int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
```

最後の要素をゲット

```java
List<String> myList = Arrays.asList("a", "b", "c");
String result = myList.stream().reduce((first, second) -> second).orElse("nothing");
//"c"
System.out.println(result);

//または
myList.get(myList.size() - 1);
//もしくは
myList.stream.skip(myList.size() - 1).findFirst().orElse("Nothing");


```
<details><summary>参考リンク</summary>
https://stackoverflow.com/questions/1128723/how-do-i-determine-whether-an-array-contains-a-particular-value-in-java
https://mkyong.com/java8/java-8-get-the-last-element-of-a-stream/
</details>


####参考リンク

https://stackify.com/streams-guide-java-8/