2021/01/26: そろそろ増えてきたので、項目ごとを記事ごとに分けようかな
時間関連
Dateを使わない、outdated、下の参照
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)
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
@PostMapping(value = "/csv", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseResult insertCsv(@RequestPart("file") MultipartFile file){
//処理
}
Service
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(ファイル作成なし)
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のもの存在しているかどうか
EnumSet<MyEnum> set = EnumSet.allOf(MyEnum.class);
boolean contains = list.stream().anyMatch(set::contains);
参考link
https://stackoverflow.com/questions/49772441/check-if-list-contains-at-least-one-of-another-enums
Lambda
lambdaのforEachで次のアイテムに行く
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);
});
}
//これはあくまでも自分独自のメソード扱い
str -> {
if (str.equals("b")) return;
System.out.println(str);
}
//これもただのloopに過ぎない
stringList.stream().forEach()
なので上の動きは細かいコードにするとこんな感じ
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);
}
参考link
https://stackoverflow.com/questions/32654929/move-to-next-item-using-java-8-foreach-loop-in-streamList関連
Listの中で複数ものが存在しているかどうかをチェック
*List.containsAllもよいが、O(NK)なので、performanceが落ちてしまう、hashsetを使えばperformanceが上がります
HashSet<String>set = new HashSet<>(list);
if(set.containsAll(Arrays.asList("asd", "efg"))){
//何かをやる
}
Listから物を削除
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);
}
参考link
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.List<Map<String, Object>>関連
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
public class DTO {
//SQLのDBではaddress
private String address;
//SQLのDBではcreated_time
private Timestamp createdTime;
}
Mapper
//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
newStringSet.addAll(oldStringSet);
Streams関連
配列で存在しているかどうか
String[] values = {"AB","BC","CD","AE"};
boolean contains = Arrays.stream(values).anyMatch("s"::equals);
primitiveではない方の探し方
int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
最後の要素をゲット
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");