{"id":3225,"date":"2025-12-24T10:00:36","date_gmt":"2025-12-24T15:00:36","guid":{"rendered":"https:\/\/www.mymiller.name\/wordpress\/?p=3225"},"modified":"2025-12-24T10:00:36","modified_gmt":"2025-12-24T15:00:36","slug":"caching-objects","status":"publish","type":"post","link":"https:\/\/www.mymiller.name\/wordpress\/java_extra\/caching-objects\/","title":{"rendered":"Caching Objects"},"content":{"rendered":"\n<p>Sometimes you need to maintain a large number of objects in memory. If it is strings you may want to take a look at <a href=\"https:\/\/www.mymiller.name\/wordpress\/programming\/java\/string-cache\/\" data-type=\"post\" data-id=\"3060\">StringCache<\/a>, which is based on my Cache class presented here. Now the Cache workers simply call create an instance of Cache: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Cache&lt;Person> peopleCache = new Cache&lt;>();<\/code><\/pre>\n\n\n\n<p>This will give you a Cache for Person objects.  The key to this, the equals() method must be implemented and able to distinguish if two objects are truly equal or not.  This is only as accurate as your equals() method.  Now to use the cache just as simple as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Person person = peopleCache.cache(somePerson);<\/code><\/pre>\n\n\n\n<p>If somePerson already exists in the cache either as itself, or as an object that is equals() then it will return the cached object to use, otherwise, it will add the somePerson object to the cache, and return the object. The complete implementation of the class can be found here:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\r\n\r\nimport name.mymiller.utils.ListUtils;\r\n\r\nimport java.lang.ref.WeakReference;\r\nimport java.util.List;\r\nimport java.util.WeakHashMap;\r\n\r\n\/**\r\n * Object Cache to remove redundant Objects that contain the same data.\r\n *\r\n * @author jmiller\r\n *\/\r\npublic class Cache&lt;E> {\r\n    \/**\r\n     * Initial capacity of the cache.\r\n     *\/\r\n    private static final int globalInitialCapacity = 65535;\r\n    \/**\r\n     * Initial Load factor to grow the map.\r\n     *\/\r\n    private static final float globalLoadFactor = (float) 0.75;\r\n    \r\n    \/**\r\n     * Number of collisions the cache has saved.\r\n     *\/\r\n    private int collisionCount = 0;\r\n    \/**\r\n     * Weak has map to allow Objects to be removed when only the cache has a link to\r\n     * them.\r\n     *\/\r\n    private WeakHashMap&lt;E, WeakReference&lt;E>> cache = null;\r\n\r\n    \/**\r\n     * Protected constructor forcing the use of the getInstance methods.\r\n     *\/\r\n    public Cache() {\r\n        this(Cache.globalInitialCapacity, Cache.globalLoadFactor);\r\n    }\r\n\r\n    \/**\r\n     * Protected constructor allowing the configuration of the capacity and load\r\n     * factor\r\n     *\r\n     * @param globalInitialCapacity Initial Capacity of the cache\r\n     * @param globalLoadFactor      Load factor for growth.\r\n     *\/\r\n    public Cache(final int globalInitialCapacity, final float globalLoadFactor) {\r\n        this.cache = new WeakHashMap&lt;>(globalInitialCapacity, globalLoadFactor);\r\n    }\r\n    \r\n    \/**\r\n     * Returns the string matching the string from the cache.\r\n     *\r\n     * @param key Object to find cache value.\r\n     * @return Cached instance of the string.\r\n     *\/\r\n    public synchronized E cache(final E key) {\r\n        E cached = null;\r\n        if (this.cache.containsKey(key)) {\r\n            final WeakReference&lt;E> ref = this.cache.get(key);\r\n\r\n            if (ref != null) {\r\n                cached = ref.get();\r\n                this.collisionCount++;\r\n            }\r\n        }\r\n\r\n        if (cached == null) {\r\n            this.cache.put(key, new WeakReference&lt;>(key));\r\n            cached = key;\r\n        }\r\n\r\n        return cached;\r\n    }\r\n\r\n    \/**\r\n     * Clears the cache\r\n     *\/\r\n    public synchronized void clear() {\r\n        this.cache.clear();\r\n        this.collisionCount = 0;\r\n    }\r\n\r\n    \/**\r\n     * Determines if the cache contains an Object.\r\n     *\r\n     * @param key Object to check if it is in the Cache.\r\n     * @return boolean indicating if the Object was found.\r\n     * @see WeakHashMap#containsKey(Object)\r\n     *\/\r\n    public synchronized boolean containsKey(final E key) {\r\n        return this.cache.containsKey(key);\r\n    }\r\n\r\n    \/*\r\n     * (non-Javadoc)\r\n     *\r\n     * @see java.name.mymiller.lang.Object#equals(java.name.mymiller.\r\n     * extensions.lang.Object)\r\n     *\/\r\n    @Override\r\n    public synchronized boolean equals(final Object obj) {\r\n        if (this == obj) {\r\n            return true;\r\n        }\r\n        if (obj == null) {\r\n            return false;\r\n        }\r\n        if (!(obj instanceof Cache)) {\r\n            return false;\r\n        }\r\n        final Cache other = (Cache) obj;\r\n        if (this.cache == null) {\r\n            return other.cache == null;\r\n        } else {\r\n            return this.cache.equals(other.cache);\r\n        }\r\n    }\r\n\r\n    \/**\r\n     * Returns a Set view of the strings this cache.\r\n     *\r\n     * @return Set View\r\n     *\/\r\n    public synchronized List&lt;E> getCached() {\r\n        return ListUtils.iterate(this.cache.keySet().iterator());\r\n    }\r\n\r\n    \/**\r\n     * @return Number of Collisions that have occurred.\r\n     *\/\r\n    public int getCollisionCount() {\r\n        return this.collisionCount;\r\n    }\r\n\r\n    \/*\r\n     * (non-Javadoc)\r\n     *\r\n     * @see java.name.mymiller.lang.Object#hashCode()\r\n     *\/\r\n    @Override\r\n    public synchronized int hashCode() {\r\n        final int prime = 31;\r\n        int result = 1;\r\n        result = (prime * result) + ((this.cache == null) ? 0 : this.cache.hashCode());\r\n        return result;\r\n    }\r\n\r\n    \/**\r\n     * Inserts an existing Object cache into this instance.\r\n     *\r\n     * @param insert Cache to insert.\r\n     *\/\r\n    protected synchronized void insertCache(final Cache&lt;E> insert) {\r\n        this.cache.putAll(insert.cache);\r\n    }\r\n\r\n    \/**\r\n     * Remove an Object from the Cache.\r\n     *\r\n     * @param key Object to remove.\r\n     *\/\r\n    public synchronized void remove(final E key) {\r\n        this.cache.remove(key);\r\n    }\r\n\r\n    \/**\r\n     * @return The size of the Cache.\r\n     * @see WeakHashMap#size()\r\n     *\/\r\n    public synchronized int size() {\r\n        return this.cache.size();\r\n    }\r\n}\r\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Sometimes you need to maintain a large number of objects in memory. If it is strings you may want to take a look at StringCache, which is based on my Cache class presented here. Now the Cache workers simply call create an instance of Cache: This will give you a Cache for Person objects. The [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3226,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[457],"tags":[69],"series":[],"class_list":["post-3225","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java_extra","tag-java-2"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2022\/02\/geocache-gd1a671d59_640.jpg?fit=640%2C360&ssl=1","jetpack-related-posts":[{"id":3060,"url":"https:\/\/www.mymiller.name\/wordpress\/java_extra\/string-cache\/","url_meta":{"origin":3225,"position":0},"title":"String Cache","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Sometimes an application will have a large number of Strings. Due to memory we certainly do not want to keep multiple instances of duplicate strings in memory. A string cache can greatly reduce the number of Strings in memory. I had a case where I had millions of strings, and\u2026","rel":"","context":"In &quot;Java Extras&quot;","block_context":{"text":"Java Extras","link":"https:\/\/www.mymiller.name\/wordpress\/category\/java_extra\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/05\/geocache-398016_640.jpg?fit=640%2C480&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/05\/geocache-398016_640.jpg?fit=640%2C480&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/05\/geocache-398016_640.jpg?fit=640%2C480&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3213,"url":"https:\/\/www.mymiller.name\/wordpress\/java_tips\/java-tips-part-4\/","url_meta":{"origin":3225,"position":1},"title":"Java Tips Part 4","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Continuing my Java Tips from experience that I have learned from code reviews to different programming tasks. Tip 16: Perform Bulk operations with Native Queries, or Stored Procedure It can be very tempting to do an update like the following: List<Person> people = ListUtils.safe(personRepository.findAll()).stream().filter person -> person.getAge() >= 60 ).map(person\u2026","rel":"","context":"In &quot;Java Tips&quot;","block_context":{"text":"Java Tips","link":"https:\/\/www.mymiller.name\/wordpress\/category\/java_tips\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/12\/sam-dan-truong-rF4kuvgHhU-unsplash-scaled-e1640791434235.jpg?fit=640%2C427&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/12\/sam-dan-truong-rF4kuvgHhU-unsplash-scaled-e1640791434235.jpg?fit=640%2C427&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/12\/sam-dan-truong-rF4kuvgHhU-unsplash-scaled-e1640791434235.jpg?fit=640%2C427&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3392,"url":"https:\/\/www.mymiller.name\/wordpress\/springboot\/spring-boot-caching\/","url_meta":{"origin":3225,"position":2},"title":"Spring Boot Caching","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Caching is a crucial aspect of building high-performance applications, and Spring Boot provides excellent support for integrating caching into your projects seamlessly. In this article, we will explore how to leverage Spring Boot's caching capabilities effectively. We will cover the basics of caching annotations, configuration, and provide practical examples to\u2026","rel":"","context":"In &quot;Springboot&quot;","block_context":{"text":"Springboot","link":"https:\/\/www.mymiller.name\/wordpress\/category\/springboot\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2022\/02\/geocache-gd1a671d59_640.jpg?fit=640%2C360&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2022\/02\/geocache-gd1a671d59_640.jpg?fit=640%2C360&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2022\/02\/geocache-gd1a671d59_640.jpg?fit=640%2C360&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3185,"url":"https:\/\/www.mymiller.name\/wordpress\/java_tips\/java-tips-part-3\/","url_meta":{"origin":3225,"position":3},"title":"Java Tips Part 3","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Continuing my Java Tips from experience that I have learned from code reviews to different programming tasks. Tip 11: Use Hibernate Statistics Now, this is only for your development profiles\/environments, not for production. Hibernate has built-in statistics on your queries. This will break down how much time is spent along\u2026","rel":"","context":"In &quot;Java Tips&quot;","block_context":{"text":"Java Tips","link":"https:\/\/www.mymiller.name\/wordpress\/category\/java_tips\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/12\/sam-dan-truong-rF4kuvgHhU-unsplash-scaled-e1640791434235.jpg?fit=640%2C427&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/12\/sam-dan-truong-rF4kuvgHhU-unsplash-scaled-e1640791434235.jpg?fit=640%2C427&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/12\/sam-dan-truong-rF4kuvgHhU-unsplash-scaled-e1640791434235.jpg?fit=640%2C427&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3614,"url":"https:\/\/www.mymiller.name\/wordpress\/java\/lombok-annotations-that-do-the-heavy-lifting\/","url_meta":{"origin":3225,"position":4},"title":"Lombok: Annotations That Do the Heavy Lifting","author":"Jeffery Miller","date":"December 23, 2025","format":false,"excerpt":"If you\u2019re a Java developer who\u2019s tired of writing repetitive boilerplate code, Lombok is your new best friend. This clever library uses annotations to automatically generate common code elements, making your classes cleaner, more concise, and less error-prone. Why Lombok? The Benefits Reduced Boilerplate: Lombok takes care of getters, setters,\u2026","rel":"","context":"In &quot;JAVA&quot;","block_context":{"text":"JAVA","link":"https:\/\/www.mymiller.name\/wordpress\/category\/java\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8314612_640.jpg?fit=640%2C480&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8314612_640.jpg?fit=640%2C480&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8314612_640.jpg?fit=640%2C480&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":2391,"url":"https:\/\/www.mymiller.name\/wordpress\/java_tips\/java-development-tips\/","url_meta":{"origin":3225,"position":5},"title":"Java Development Tips","author":"Jeffery Miller","date":"December 23, 2025","format":false,"excerpt":"Java-based servers or applications often have to deal with large amounts of data.\u00a0 Whether the data is from a database, or from a local file, processing this data in an efficient manner is a priority for maintainability. In this article, we will discuss the types of Java Data Objects and\u2026","rel":"","context":"In &quot;Java Tips&quot;","block_context":{"text":"Java Tips","link":"https:\/\/www.mymiller.name\/wordpress\/category\/java_tips\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2018\/10\/archive-1850170_640.jpg?fit=640%2C426&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2018\/10\/archive-1850170_640.jpg?fit=640%2C426&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2018\/10\/archive-1850170_640.jpg?fit=640%2C426&ssl=1&resize=525%2C300 1.5x"},"classes":[]}],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3225","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/comments?post=3225"}],"version-history":[{"count":1,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3225\/revisions"}],"predecessor-version":[{"id":3227,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3225\/revisions\/3227"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media\/3226"}],"wp:attachment":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media?parent=3225"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/categories?post=3225"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/tags?post=3225"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/series?post=3225"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}