{"id":4082,"date":"2021-12-09T08:19:36","date_gmt":"2021-12-08T23:19:36","guid":{"rendered":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=4082"},"modified":"2021-12-09T11:59:31","modified_gmt":"2021-12-09T02:59:31","slug":"java-oop","status":"publish","type":"post","link":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=4082","title":{"rendered":"JAVA OOP, Generic, Collection"},"content":{"rendered":"<h1>JAVA OOP, Generic, Collection<\/h1>\n<p><a href=\"https:\/\/velog.io\/@vincentj2\/JAVA-OOP%EB%9E%80\">\ucc38\uc870<\/a><br \/>\n<a href=\"https:\/\/javaoop.tistory.com\/m\/25\">\ucc38\uc870<\/a><\/p>\n<h2>OOP\uc758 \ud2b9\uc9d5 4\uac00\uc9c0<\/h2>\n<h3>\ucea1\uc290\ud654(Encapsulation)<\/h3>\n<p>\uad6c\ud604\uc744 \uc678\ubd80\uc5d0 \uc228\uae30\ub294 \uac83\uc744 \uc758\ubbf8\ud569\ub2c8\ub2e4.<br \/>\n(\ub77c\uace0 \uc368\ub193\uace0 \ub85c\uc9c1\uc744 \ud074\ub798\uc2a4\uc5d0 \ubab0\uc544 \ub123\ub294\ub2e4\ub77c\uace0 \ud574\uc11d\ud569\ub2c8\ub2e4.)<\/p>\n<pre><code class=\"language-java\">public class CustomerOrder {\n    private String cancelyn;\n    public void cancel() {\n        this.cancelyn = &quot;Y&quot;;\n        \/\/ \ub9c8\uc77c\ub9ac\uc9c0 \uad00\ub828 \ub85c\uc9c1\n        \/\/ \ucfe0\ud3f0 \uad00\ub828 \ub85c\uc9c1\n        \/\/ \uc7ac\uace0 \uad00\ub828 \ub85c\uc9c1\n    }\n}\n\nCustomerOrder customerOrder = new CustomerOrder();\ncustomerOrder.cancel();<\/code><\/pre>\n<p>\uad6c\ud604\uc744 \uc228\uae30\uc9c0 \uc54a\uc73c\uba74 \uc5b4\ub5bb\uac8c \ub420\uae4c\uc694?<\/p>\n<pre><code class=\"language-java\">public class CustomerOrder {\n    public String cancelyn;\n}\n\nCustomerOrder customerOrder = new CustomerOrder();\ncustomerOrder.cancelyn = &quot;Y&quot;;\n\/\/ \ub9c8\uc77c\ub9ac\uc9c0 \uad00\ub828 \ub85c\uc9c1\n\/\/ \ucfe0\ud3f0 \uad00\ub828 \ub85c\uc9c1\n\/\/ \uc7ac\uace0 \uad00\ub828 \ub85c\uc9c1<\/code><\/pre>\n<p>\ub9cc\uc57d canceldate \ub97c \ucd94\uac00\ud558\uace0\uc790 \ud55c\ub2e4\uba74?<\/p>\n<pre><code class=\"language-java\">public class CustomerOrder {\n    public String cancelyn;\n    public LocalDateTime canceldate;\n}\n\nCustomerOrder customerOrder = new CustomerOrder();\ncustomerOrder.cancelyn = &quot;Y&quot;;\ncustomerOrder.canceldate = LocalDateTime.now();\n\/\/ \ub9c8\uc77c\ub9ac\uc9c0 \uad00\ub828 \ub85c\uc9c1\n\/\/ \ucfe0\ud3f0 \uad00\ub828 \ub85c\uc9c1\n\/\/ \uc7ac\uace0 \uad00\ub828 \ub85c\uc9c1<\/code><\/pre>\n<p>\ucde8\uc18c \uae30\ub2a5\uc774 \uc788\ub294 \uacf3\uc774 \ub2e4\uc218\ub77c\uba74, \ucc3e\uc544\ub2e4\ub2c8\uba74\uc11c \ud558\ub098\ud558\ub098 \ucf54\ub4dc\ub97c \ucd94\uac00\ud574 \uc8fc\uc5b4\uc57c \ud569\ub2c8\ub2e4.<br \/>\n\ubabb \ucc3e\uc740 \uacf3\uc774 \ubc1c\uc0dd\ud558\uba74 \ubc84\uadf8\uac00 \ub429\ub2c8\ub2e4.<\/p>\n<p>\ubaa8\ub450 \ucc3e\uc558\ub2e4 \ud574\ub3c4, \uc911\ubcf5\ucf54\ub4dc\uac00 \uc0b0\uc9c0\uc0ac\ubc29\uc5d0 \ud37c\uc9c0\uac8c \ub429\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">public class CustomerOrder {\n    private String cancelyn;\n    public LocalDateTime canceldate;\n    public void cancel() {\n        this.cancelyn = &quot;Y&quot;;\n        this.canceldate = LocalDateTime.now();\n        \/\/ \ub9c8\uc77c\ub9ac\uc9c0 \uad00\ub828 \ub85c\uc9c1\n        \/\/ \ucfe0\ud3f0 \uad00\ub828 \ub85c\uc9c1\n        \/\/ \uc7ac\uace0 \uad00\ub828 \ub85c\uc9c1\n    }\n}\n\nCustomerOrder customerOrder = new CustomerOrder();\ncustomerOrder.cancel();<\/code><\/pre>\n<p>\ucea1\uc290\ud654\ud588\ub2e4\uba74 \uba54\uc18c\ub4dc \ud558\ub098\ub9cc \uc218\uc815\ud574\uc8fc\uba74 \ub05d\ub0a9\ub2c8\ub2e4.<\/p>\n<h3>\uc0c1\uc18d(Inheritance)<\/h3>\n<p>2\uac1c \uc774\uc0c1\uc758 \ud074\ub798\uc2a4\uc5d0\uc11c \uc911\ubcf5\ub418\ub294 \ucf54\ub4dc\ub97c \ubd80\ubaa8 \ud074\ub798\uc2a4\ub85c \ub9cc\ub4e4\uae30\ub3c4 \ud558\uace0,<br \/>\n\ud558\ub098\uc758 \ud074\ub798\uc2a4\uc5d0\uc11c \uae30\ub2a5\ud655\uc7a5\uc744 \uc704\ud574 \uc790\uc2dd \ud074\ub798\uc2a4\ub97c \ub9cc\ub4e4\uae30\ub3c4 \ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">\/\/ \uace0\uac1d \uc8fc\ubb38\npublic class CustomerOrder { }\n\n\/\/ \uaf43\ubc30\ub2ec \uace0\uac1d \uc8fc\ubb38\npublic class FlowerCustomerOrder extends CustomerOrder {\n    \/\/ \uaf43\ubc30\ub2ec \uad00\ub828 \ub85c\uc9c1\ub9cc \ucd94\uac00\n}\n\n\/\/ \ud574\uc678\ubc30\uc1a1 \uace0\uac1d \uc8fc\ubb38\npublic class ForeignCustomerOrder extends CustomerOrder {\n    \/\/ \ud574\uc678\ubc30\uc1a1 \uad00\ub828 \ub85c\uc9c1\ub9cc \ucd94\uac00\n}<\/code><\/pre>\n<pre><code class=\"language-java\">\/\/ \ubcf4\ub108\uc2a4 \ucfe0\ud3f0\npublic class BonusCoupon { }\n\n\/\/ \ube44\uc728 \ubcf4\ub108\uc2a4 \ucfe0\ud3f0\npublic class PercentBonusCoupon extends BonusCoupon { }\n\n\/\/ \uae08\uc561 \ubcf4\ub108\uc2a4 \ucfe0\ud3f0\npublic class PriceBonusCoupon extends BonusCoupon { }<\/code><\/pre>\n<h3>\ucd94\uc0c1\ud654(Abstraction)<\/h3>\n<p>\ud544\uc694\ud55c \uae30\ub2a5\uc740 \uc54c\uaca0\ub294\ub370, \ucf54\ub4dc\ub97c \uc791\uc131\ud560 \uc218 \uc5c6\uc744 \ub54c \uc0ac\uc6a9\ud569\ub2c8\ub2e4.<\/p>\n<p>\uc544\ub798\uc758 \ucf54\ub4dc\uc5d0\uc11c getDiscountPrice() \ucc98\ub7fc, \ud544\uc694\ud55c \uae30\ub2a5\uc740 \uc788\uc9c0\ub9cc,<br \/>\n\uc2e4\uc81c\ub85c \ucf54\ub4dc\ub97c \uc791\uc131\ud560 \uc218 \uc5c6\uc744\ub54c <code>abstract<\/code> \ub85c \ucd94\uc0c1\ud074\ub798\uc2a4\ub97c \ub9cc\ub4e4\uace0,<br \/>\n\uc790\uc2dd \ud074\ub798\uc2a4\uc5d0\uc11c \uc2e4\uc81c \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub3c4\ub85d \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">public class OrderProduct {\n    private BigDecimal price;\n    private int orderCount;\n    \/\/ getter &amp; setter\n}\n\n\/\/ \ucd94\uc0c1 \ud074\ub798\uc2a4\npublic abstract class BonusCoupon {\n    \/\/ \ucd94\uc0c1 \uba54\uc18c\ub4dc\n    public abstract BigDecimal getDiscountPrice(List&lt;OrderProduct&gt; items, int index);\n}\n\npublic class PercentBonusCoupon extends BonusCoupon {\n    @Override\n    public BigDecimal getDiscountPrice(List&lt;OrderProduct&gt; items, int index) {\n        \/\/ \ube44\uc728\ucfe0\ud3f0 \uacc4\uc0b0 \ub85c\uc9c1\n        return BigDecimal.ZERO;\n    }\n}\n\npublic class PriceBonusCoupon extends BonusCoupon {\n    @Override\n    public BigDecimal getDiscountPrice(List&lt;OrderProduct&gt; items, int index) {\n        \/\/ \uae08\uc561\ucfe0\ud3f0 \uacc4\uc0b0 \ub85c\uc9c1\n        return BigDecimal.ZERO;\n    }\n}<\/code><\/pre>\n<p>\ucd94\uc0c1\ud654\uc758 \uadf9\ub2e8\uc801\uc778 \uc608\ub85c <code>interface<\/code> \uac00 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">public interface List&lt;E&gt; extends Collection&lt;E&gt; {\n    int size();\n    boolean isEmpty();\n    \/\/ ......\n}<\/code><\/pre>\n<p>\ucd94\uc0c1 \ud074\ub798\uc2a4\ub294 \uc77c\ubd80 \uba54\uc18c\ub4dc\uc758 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc9c0 \uc54a\ub294 \uac83\uc774\uace0,<br \/>\n\uc778\ud130\ud398\uc774\uc2a4\ub294 \ubaa8\ub4e0 \uba54\uc18c\ub4dc\uc758 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.<br \/>\n\ub610\ud55c, <code>abstract<\/code> \ud0a4\uc6cc\ub4dc\ub97c \uc0dd\ub7b5\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<h3>\ub2e4\ud615\uc131(Polymorphism)<\/h3>\n<p>\uc704\ud0a4\ud53c\ub514\uc544\uc5d0 \uc544\ub798\uc640 \uac19\uc774 \uc124\uba85\ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<blockquote>\n<p>\ud504\ub85c\uadf8\ub7a8 \uc5b8\uc5b4\uc758 \ub2e4\ud615\uc131(\u591a\u5f62\u6027, polymorphism; \ud3f4\ub9ac\ubaa8\ud53c\uc998)\uc740 \uadf8 \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4\uc758 \uc790\ub8cc\ud615 \uccb4\uacc4\uc758 \uc131\uc9c8\uc744 \ub098\ud0c0\ub0b4\ub294 \uac83\uc73c\ub85c, \ud504\ub85c\uadf8\ub7a8 \uc5b8\uc5b4\uc758 \uac01 \uc694\uc18c\ub4e4(\uc0c1\uc218, \ubcc0\uc218, \uc2dd, \uc624\ube0c\uc81d\ud2b8, \ud568\uc218, \uba54\uc18c\ub4dc \ub4f1)\uc774 \ub2e4\uc591\ud55c \uc790\ub8cc\ud615(type)\uc5d0 \uc18d\ud558\ub294 \uac83\uc774 \ud5c8\uac00\ub418\ub294 \uc131\uc9c8\uc744 \uac00\ub9ac\ud0a8\ub2e4. \ubc18\ub313\ub9d0\uc740 \ub2e8\ud615\uc131(monomorphism)\uc73c\ub85c, \ud504\ub85c\uadf8\ub7a8 \uc5b8\uc5b4\uc758 \uac01 \uc694\uc18c\uac00 \ud55c\uac00\uc9c0 \ud615\ud0dc\ub9cc \uac00\uc9c0\ub294 \uc131\uc9c8\uc744 \uac00\ub9ac\ud0a8\ub2e4.<\/p>\n<\/blockquote>\n<p>\ub9d0\uc774 \ubcf5\uc7a1\ud55c\ub370&#8230;<br \/>\n\uc790\ubc14\uc5d0\uc11c \ub300\ud45c\uc801\uc73c\ub85c \uc0ac\uc6a9\ub418\ub294 \ub450\uac00\uc9c0 \ucf00\uc774\uc2a4\ub97c \ud655\uc778\ud574 \ubd05\ub2c8\ub2e4.<\/p>\n<h4>\uac1d\uccb4 \ub2e4\ud615\uc131<\/h4>\n<pre><code class=\"language-java\">public class CustomerOrder {\n    public void applyCoupon(BonusCoupon coupon) {\n        \/\/ \ucfe0\ud3f0 \uc801\uc6a9\ub85c\uc9c1\n    }\n}\n\nCustomerOrder customerOrder = new CustomerOrder();\nPercentBonusCoupon percentBonusCoupon = new PercentBonusCoupon();\nPriceBonusCoupon priceBonusCoupon = new PriceBonusCoupon();\n\n\/\/ customerOrder.applyCoupon(percentBonusCoupon);\n\/\/ or\ncustomerOrder.applyCoupon(priceBonusCoupon);<\/code><\/pre>\n<p>\uba54\uc18c\ub4dc\ub97c <code>applyCoupon(BonusCoupon coupon)<\/code> \ub85c \uc9c0\uc815\ud568\uc73c\ub85c \ud574\uc11c,<br \/>\nBonusCoupon \uc744 \uc0c1\uc18d\ud558\ub294 \ubaa8\ub4e0 \ud074\ub798\uc2a4\ub97c \ub300\uc785\ud560 \uc218 \uc788\ub294 \uac83\uc744 \ubcfc \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\ucd94\uc0c1\ud654\ub97c \uc124\uba85\ud560 \ub54c <code>getDiscountPrice()<\/code> \ub97c \uae30\ub2a5 \uad6c\ud604\ub3c4 \ubabb\ud558\ub294\ub370,<br \/>\n\uc65c \uad82\uc774 \ucd94\uac00\ud574 \ub193\uc744\uae4c\uc758 \ub300\ub2f5\uc774 \uc5ec\uae30\uc11c \ub098\uc635\ub2c8\ub2e4.<br \/>\n\ucd94\uc0c1 \uba54\uc18c\ub4dc\ub77c\ub3c4 \ucd94\uac00\ud574 \ub193\uc558\uae30 \ub54c\ubb38\uc5d0,<br \/>\n\uae08\uc561\ucfe0\ud3f0 \ub610\ub294 \ube44\uc728\ucfe0\ud3f0\uc758 getDiscountPrice() \ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\uac8c \ub429\ub2c8\ub2e4.<\/p>\n<p>\uc720\uc6a9\ud55c \uae30\ub2a5\uc73c\ub85c, \ub9e4\uc6b0 \ub9ce\uc774 \uc4f0\uc774\ub294 \uc18d\uc131\uc785\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">List&lt;CustomerOrder&gt; customerOrders = new ArrayList&lt;&gt;();<\/code><\/pre>\n<p>\uc704\uc758 \uacbd\uc6b0\ub3c4 <code>List<\/code> \uc5d0 List \uc758 \ud558\uc704\uac1d\uccb4\uc778 <code>ArrayList<\/code> \ub97c \ub300\uc785\ud558\ub294 \uacbd\uc6b0\uc785\ub2c8\ub2e4.<br \/>\n(\uc815\ud655\ud788\ub294 \uc778\ud130\ud398\uc774\uc2a4 \uad6c\ud604\uccb4\uc774\uc9c0\ub9cc)<\/p>\n<h4>\uba54\uc18c\ub4dc \ub2e4\ud615\uc131<\/h4>\n<p>\uba54\uc18c\ub4dc \ub2e4\ud615\uc131\uc5d0\ub294 \uba54\uc18c\ub4dc \uc624\ubc84\ub85c\ub529, \uba54\uc18c\ub4dc \uc624\ubc84\ub77c\uc774\ub529\uc774 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<ul>\n<li>\n<p>\uba54\uc18c\ub4dc \uc624\ubc84\ub85c\ub529<\/p>\n<p>\uba54\uc18c\ub4dc\uba85\uc774 \ub3d9\uc77c\ud558\uace0, \ud30c\ub77c\ubbf8\ud130 \ud0c0\uc785(Type)\uc740 \ub2e4\ub978 \uacbd\uc6b0\uc785\ub2c8\ub2e4.<br \/>\n<code>String.valueOf()<\/code> \ucc98\ub7fc \uba54\uc18c\ub4dc\uba85\uc774 \ub3d9\uc77c\ud558\uc9c0\ub9cc, \ud30c\ub77c\ubbf8\ud130 \ud0c0\uc785\uc740 \uc804\ubd80 \ub2e4\ub985\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">int i = 1;\nString j = new String(&quot;2&quot;);\nfloat k = 3;\n\nSystem.out.println(String.valueOf(i));\nSystem.out.println(String.valueOf(j));\nSystem.out.println(String.valueOf(k));<\/code><\/pre>\n<\/li>\n<li>\n<p>\uba54\uc18c\ub4dc \uc624\ubc84\ub77c\uc774\ub529<\/p>\n<p>\uba54\uc18c\ub4dc\uba85\uacfc \ud30c\ub77c\ubbf8\ud130\uac00 \ubaa8\ub450 \ub3d9\uc77c\ud55c \uacbd\uc6b0\uc785\ub2c8\ub2e4.<br \/>\nBigDecimal getDiscountPrice(List<OrderProduct> items, int index) \ucc98\ub7fc,<br \/>\n\uba54\uc18c\ub4dc\uba85, \ud30c\ub77c\ubbf8\ud130 \ud0c0\uc785, \ub9ac\ud134\uac12 \ubaa8\ub450 \ub3d9\uc77c\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">public abstract class BonusCoupon {\n  public abstract BigDecimal getDiscountPrice(List&lt;OrderProduct&gt; items, int index);\n}\n\npublic class PercentBonusCoupon extends BonusCoupon {\n  @Override\n  public BigDecimal getDiscountPrice(List&lt;OrderProduct&gt; items, int index) {\n      \/\/ \ube44\uc728\ucfe0\ud3f0 \uacc4\uc0b0 \ub85c\uc9c1\n      return BigDecimal.ZERO;\n  }\n}<\/code><\/pre>\n<\/li>\n<\/ul>\n<h2>Generic<\/h2>\n<p>\ud074\ub798\uc2a4\ub97c \ud30c\ub77c\ubbf8\ud130\ub85c \ubc1b\uc744 \uc218 \uc788\ub294 \uae30\ub2a5\uc785\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">List&lt;CustomerOrder&gt; customerOrders = new ArrayList&lt;&gt;();<\/code><\/pre>\n<p>Generic \uc774 \uc5c6\ub2e4\uba74?<\/p>\n<pre><code class=\"language-java\">StringList stringList = new StringList();\nIntegerList integerList = new IntegerList();\nCustomerOrderList customerOrderList = new CustomerOrderList();\n\/\/ ......<\/code><\/pre>\n<p>\uac01\uac01\uc758 \uac1d\uccb4\uc5d0 \ub300\ud574 \uac01\uac01\uc758 List \ud074\ub798\uc2a4\ub97c \uc0dd\uc131\ud574\uc57c \ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">public interface List&lt;E&gt; extends Collection&lt;E&gt; {\n    int size();\n    boolean isEmpty();\n    boolean contains(Object o);\n    \/\/ ......\n}<\/code><\/pre>\n<p>\ub610\ud55c, List \uc5d0\uc11c \uae30\ubcf8\uc801\uc73c\ub85c \ud544\uc694\ud55c \uba54\uc18c\ub4dc\ub4e4\uc744 \uac01\uac01\uc758 \ud074\ub798\uc2a4\uc5d0 \uad6c\ud604\ud574 \uc8fc\uc5b4\uc57c \ud558\uace0,<br \/>\n\ucf54\ub4dc\uc911\ubcf5\uc774 \ubc1c\uc0dd\ud560 \uc218\ubc16\uc5d0 \uc5c6\uc2b5\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">import org.mapstruct.BeanMapping;\nimport org.mapstruct.MappingTarget;\nimport org.mapstruct.NullValuePropertyMappingStrategy;\n\npublic interface GenericMapper&lt;D, E&gt; {\n\n    D toDto(E e);\n    E toEntity(D d);\n\n    @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)\n    void updateFromDto(D dto, @MappingTarget E entity);\n}<\/code><\/pre>\n<p>\uc704\uc640 \uac19\uc774 Generic interface \ub97c \uc0dd\uc131\ud574 \uc900 \uacbd\uc6b0,<br \/>\n\uc544\ub798\uc640 \uac19\uc774 \ud074\ub798\uc2a4 \ud30c\ub77c\ubbf8\ud130\ub97c \uc9c0\uc815\ud574 \uc8fc\ub294\uac83\ub9cc\uc73c\ub85c \ucf54\ub529\uc774 \ub05d\ub0a9\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">@Mapper(componentModel = &quot;spring&quot;, unmappedTargetPolicy = ReportingPolicy.IGNORE)\npublic interface UserInfoMapper extends GenericMapper&lt;UserInfoDto, UserInfo&gt; {\n}<\/code><\/pre>\n<p>\uba54\uc18c\ub4dc \ub4f1\uc5d0\ub3c4 \ud074\ub798\uc2a4 \ud30c\ub77c\ubbf8\ud130\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br \/>\n<code>abstract<\/code> \ub85c \uc9c0\uc815\ud55c \uba54\uc18c\ub4dc \uc774\uc678\uc5d0\ub294 \ucf54\ub4dc\uac00 \uc790\ub3d9\uc0dd\uc131\ub418\ubbc0\ub85c,<br \/>\n\ubcc4\ub3c4\uc758 \ucf54\ub529\uc774 \ud544\uc694\uc5c6\uc2b5\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">\/**\n *\n * CustomGenericService - \uc11c\ube44\uc2a4\uc758 \uacf5\ud1b5 \uae30\ub2a5 \ucd94\uc0c1\ud654(CRUD)\n * \uc7ac\uc815\uc758\uac00 \ud544\uc694\ud55c \uae30\ub2a5\uc740 @Override\ud574\uc11c \uc0ac\uc6a9\ud560\uac83\n *\n * @author skyer9@gmail.com\n *\n * @param &lt;D&gt; DTO Type\n * @param &lt;E&gt; Entity Type\n * @param &lt;KD&gt; Key DTO Type\n * @param &lt;KE&gt; Key Entity type\n *\/\n\npublic abstract class CustomGenericService&lt;D, E, KD, KE&gt; {\n\n    protected JpaRepository&lt;E, KE&gt; repository;\n    protected final String title;\n\n    public CustomGenericService(JpaRepository&lt;E, KE&gt; repository, String title) {\n\n        this.repository = repository;\n        this.title = title;\n    }\n\n    \/\/ \uc0dd\uc131\n    @Transactional\n    public D create(D d) {\n\n        E e = newEntity();\n        updateFromDto(d, e);\n\n        return toDto(repository.save(e));\n    }\n\n    \/\/ \uccb4\ud06c \ubc0f \uc0dd\uc131\n    @Transactional\n    public D create(KD id, D d) throws DataExistsException {\n\n        KE ke = toKeyEntity(id);\n\n        if (get(ke, false) != null) {\n            throw new DataExistsException(title + &quot;\uc774(\uac00) \uc774\ubbf8 \uc874\uc7ac\ud569\ub2c8\ub2e4.&quot;);\n        }\n\n        E e = newEntity(ke);\n        updateFromDto(d, e);\n\n        return toDto(repository.save(e));\n    }\n\n    \/\/ \uc218\uc815\n    @Transactional\n    public void update(KD id, D d) {\n\n        E e = get(toKeyEntity(id), true);\n        updateFromDto(d, e);\n        repository.save(e);\n    }\n\n    \/\/ \uc218\uc815 \ub610\ub294 \uc0dd\uc131\n    @Transactional\n    public void updateOrCreate(KD id, D d) {\n\n        E e = get(toKeyEntity(id));\n        updateFromDto(d, e);\n        repository.save(e);\n    }\n\n    \/\/ DTO \uc870\ud68c\n    @Transactional(readOnly = true)\n    public D select(KD id) {\n\n        return toDto(get(toKeyEntity(id), true));\n    }\n\n    \/\/ Entity \ubc18\ud658\n    @Transactional\n    public E get(KE id, boolean throwExceptionIfNotExists) {\n\n        E e = repository.findById(id).orElse(null);\n\n        if (throwExceptionIfNotExists &amp;&amp; (e == null)) {\n            throw new DataNotFoundException(title + &quot;\uc774(\uac00) \uc874\uc7ac\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.&quot;);\n        } else {\n            return e;\n        }\n    }\n\n    @Transactional\n    public E get(KE id) {\n        Optional&lt;E&gt; o = repository.findById(id);\n        return o.orElseGet(() -&gt; newEntity(id));\n    }\n\n    public abstract SearchResponseDto search(Map&lt;String, String&gt; params);\n\n    protected List&lt;D&gt; toDto(List&lt;E&gt; lst) {\n\n        return lst.stream().map(this::toDto).collect(Collectors.toList());\n    }\n\n    protected abstract D toDto(E e);\n    protected abstract E toEntity(D e);\n    \/\/ protected abstract KD toKeyDto(KE e);\n    protected abstract KE toKeyEntity(KD e);\n    protected abstract void updateFromDto(D d, E e);\n    protected abstract E newEntity();\n    protected abstract E newEntity(KE e);\n}<\/code><\/pre>\n<h2>Collection<\/h2>\n<p>API \uc11c\ubc84 \uac1c\ubc1c\uc5d0\ub294 \uc4f0\ub2e4\ubcf4\ub2c8 \ub531 \ub450\uac1c\ub9cc \uc4f0\uac8c \ub418\ub354\uad70\uc694.<\/p>\n<h3>HashMap<\/h3>\n<p>\uc8fc\ub85c URL \ud30c\ub77c\ubbf8\ud130 \uc124\uc815\ud560 \ub54c \uc501\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">Map&lt;String, String&gt; map = new HashMap&lt;&gt;();\n\nmap.put(&quot;searchKeyword&quot;, &quot;\uc544\uc774\ud3f0\ucf00\uc774\uc2a4&quot;);\nmap.put(&quot;pageNumber&quot;, &quot;1&quot;);\nmap.put(&quot;pageSize&quot;, &quot;20&quot;);\n\nSystem.out.println(map.get(&quot;searchKeyword&quot;));<\/code><\/pre>\n<h3>ArrayList<\/h3>\n<p>\uc8fc\ub85c \uac80\uc0c9\uacb0\uacfc\ub97c \ubc18\ud658\ud560 \ub54c \uc0ac\uc6a9\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">List&lt;Object&gt; results = Arrays.asList(toDto(list).toArray());<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>JAVA OOP, Generic, Collection \ucc38\uc870 \ucc38\uc870 OOP\uc758 \ud2b9\uc9d5 4\uac00\uc9c0 \ucea1\uc290\ud654(Encapsulation) \uad6c\ud604\uc744 \uc678\ubd80\uc5d0 \uc228\uae30\ub294 \uac83\uc744 \uc758\ubbf8\ud569\ub2c8\ub2e4. (\ub77c\uace0 \uc368\ub193\uace0 \ub85c\uc9c1\uc744 \ud074\ub798\uc2a4\uc5d0 \ubab0\uc544 \ub123\ub294\ub2e4\ub77c\uace0 \ud574\uc11d\ud569\ub2c8\ub2e4.) public class CustomerOrder { private String cancelyn; public void cancel() { this.cancelyn = &quot;Y&quot;; \/\/ \ub9c8\uc77c\ub9ac\uc9c0 \uad00\ub828 \ub85c\uc9c1 \/\/ \ucfe0\ud3f0 \uad00\ub828 \ub85c\uc9c1 \/\/ \uc7ac\uace0 \uad00\ub828 \ub85c\uc9c1 } } CustomerOrder customerOrder = new CustomerOrder();\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=4082\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-4082","post","type-post","status-publish","format-standard","hentry","category-java"],"_links":{"self":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/4082","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4082"}],"version-history":[{"count":34,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/4082\/revisions"}],"predecessor-version":[{"id":4119,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/4082\/revisions\/4119"}],"wp:attachment":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4082"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4082"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4082"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}