<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[neOO0的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/neOO0</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; neOO0]]></copyright><item><title><![CDATA[《Effective Java》漫谈：继承带来的equals难题]]></title><link>https://blog.youkuaiyun.com/neOO0/article/details/133984667</link><guid>https://blog.youkuaiyun.com/neOO0/article/details/133984667</guid><author>neOO0</author><pubDate>Tue, 24 Oct 2023 16:12:21 +0800</pubDate><description><![CDATA[传递性: 对于任何非空引用值 x、 y 和 z，如果 x.equals (y)返回 true，而 y.equals (z)返回 true，那么 x.equals (z)应该返回 true。对称性: 对于任何非空引用值 x 和 y，当且仅当 y.equals (x)返回 true 时，x.equals (y)应该返回 true。自反性: 对于任何非空引用值 x，x.equals (x)应该返回 true。对于任何非空的引用值 x，x.equals (null)应该返回 false。我们可以考虑这样修改。]]></description><category></category></item><item><title><![CDATA[《Effective Java》漫谈：被废弃的终结方法]]></title><link>https://blog.youkuaiyun.com/neOO0/article/details/133959161</link><guid>https://blog.youkuaiyun.com/neOO0/article/details/133959161</guid><author>neOO0</author><pubDate>Sun, 22 Oct 2023 01:30:04 +0800</pubDate><description><![CDATA[翻开Object源码，其中定义了空方法finalize()，我们看一下文档中的解释当垃圾回收器确定不再有对对象的引用时，由对象上的垃圾回收器调用。子类重写finalize方法以释放系统资源或执行其他清理。finalize方法可以执行任何操作，包括使该对象再次对其他线程可用;然而，finalize的通常目的是在对象被不可撤消地丢弃之前执行清理操作。例如，表示输入/输出连接的对象的finalize方法可能会执行显式的I/O事务，以在永久丢弃该对象之前中断连接。创建一个。]]></description><category></category></item><item><title><![CDATA[《Effective Java》第7条：消除过期的对象引用]]></title><link>https://blog.youkuaiyun.com/neOO0/article/details/133938749</link><guid>https://blog.youkuaiyun.com/neOO0/article/details/133938749</guid><author>neOO0</author><pubDate>Fri, 20 Oct 2023 17:45:43 +0800</pubDate><description><![CDATA[来实现删除元素的效果，会发生什么？答案是：从一个表中删除的对象不会被回收，因为实际上表内部依然维护着这些对象的引用，只不过我们通过限制访问，所以无法查看罢了。当然不会忽略这个问题，但是只要是类自己管理内存，我们就应该警惕可能发生的内存泄露问题。为例，想要了解原理的读者可以看一下源码，这里指简单讲一下。假设一开始创建容量为16的数组，初始化之后数组为空，因此。因此如果要从表中删除元素，需要先将它清空，再修改。要从上面这个表中删除最后一个元素，可以直接把。设为2，这样就无法查看最后一个元素了。]]></description><category></category></item><item><title><![CDATA[《Effective Java》第6条：避免创建不必要的对象]]></title><link>https://blog.youkuaiyun.com/neOO0/article/details/133916354</link><guid>https://blog.youkuaiyun.com/neOO0/article/details/133916354</guid><author>neOO0</author><pubDate>Thu, 19 Oct 2023 20:53:50 +0800</pubDate><description><![CDATA[运行时常量池和常量池是两个不同的概念，JVM在完成类装载操作时，会将常量池中的内容载入内存，并保存在方法区中的运行时常量池，如果是字符串的话，会先在堆中创建字符串对象实例，然后将该对象的引用放到堆中的字符串常量池中，最后将运行时常量池里的符号引用替换成直接引用。方法时传入的参数范围在-128~127间，会直接返回常量池中数据的引用，否则创建新对象，不多展开，感兴趣的可以看一下源码。“该语句每次被执行的时候都创建一个新的String实例，但是这些创建对象的动作都是不必要的。反汇编后可以发现自动调用了。]]></description><category></category></item><item><title><![CDATA[《Effective Java》第5条：优先考虑依赖注入来引用资源]]></title><link>https://blog.youkuaiyun.com/neOO0/article/details/133901921</link><guid>https://blog.youkuaiyun.com/neOO0/article/details/133901921</guid><author>neOO0</author><pubDate>Wed, 18 Oct 2023 11:31:39 +0800</pubDate><description><![CDATA[当一个类的实现需要依赖一个或多个底层资源时，可以利用依赖注入，将这些资源传给构造器、静态工厂或者构建器，通过来们来创建类。通过filed注入的方式不理想，因为它无法支持多资源。3. 通过setter方法注入。1. 通过filed注入。2. 通过构造器注入。先创建Book资源类。]]></description><category></category></item><item><title><![CDATA[《Effective Java》第4条：通过私有构造器强化不可实例化的能力]]></title><link>https://blog.youkuaiyun.com/neOO0/article/details/133898071</link><guid>https://blog.youkuaiyun.com/neOO0/article/details/133898071</guid><author>neOO0</author><pubDate>Wed, 18 Oct 2023 09:27:41 +0800</pubDate><description><![CDATA[当类不包含显式的构造器时，编译器会自动生成公有的、无参的缺省构造器，只要让一个类包含一个私有构造器，它就不能被实例化。但是这种类无法子类化，因为所有的构造器必须显式或隐式地调用超类构造器，这种情况下，子类没有可访问的超类构造器可用。即使将类做成抽象类，通过继承的方式仍然可以实现实例化，而且会让用户误以为该类是专门为了继承而设计的。]]></description><category></category></item><item><title><![CDATA[《Effective Java》第3条：用私有构造器或者枚举类型强化Singleton属性]]></title><link>https://blog.youkuaiyun.com/neOO0/article/details/133887517</link><guid>https://blog.youkuaiyun.com/neOO0/article/details/133887517</guid><author>neOO0</author><pubDate>Tue, 17 Oct 2023 21:40:19 +0800</pubDate><description><![CDATA[为了将利用上述方法实现的Singleton类变成可序列化的，需要声明所有实例域都是瞬时（tansient）的，并提供一个readResolve方法，否则反序列化后会创建新的实例。1. 自带序列化机制，更加简洁，同时能够防御反序列化攻击。反序列化得到的对象和序列化的对象是同一个。3. 声明一个包含单个元素的枚举类。1. 公有静态成员为final域。为什么枚举是单例模式的最佳方法？2. 公有成员为静态工厂方法。2.  能够阻止反射攻击。]]></description><category></category></item><item><title><![CDATA[《Effective Java》第2条：遇到多个构造器参数时要考虑使用构建器]]></title><link>https://blog.youkuaiyun.com/neOO0/article/details/133850972</link><guid>https://blog.youkuaiyun.com/neOO0/article/details/133850972</guid><author>neOO0</author><pubDate>Mon, 16 Oct 2023 10:45:04 +0800</pubDate><description><![CDATA[还有诸如参数可以在调用build方法来创建对象期间进行调整或者随着不同的对象而改变、自动填充某些域等优势，不再赘述。重叠构造器提供的第一个构造器只有必要的参数，第二个构造器有一个可选参数，第三个构造器有两个可选参数，以此类推。先使用无参构造器创建对象，再调用setter方法来设置每个必要的参数。连续调用两次addPress方法，可以将传入的参数集中到press里面。静态工厂和构造器有一个共同的局限性：不能很好地扩展到大量的可选参数。1. 可以将多次调用某一个方法而传入的参数集中到一个域中。]]></description><category></category></item><item><title><![CDATA[链表的操作]]></title><link>https://blog.youkuaiyun.com/neOO0/article/details/133845955</link><guid>https://blog.youkuaiyun.com/neOO0/article/details/133845955</guid><author>neOO0</author><pubDate>Sun, 15 Oct 2023 20:17:56 +0800</pubDate><description><![CDATA[如果直接将单链表的反转复用到双链表上，会发现最后每个结点的prev和next链接域指向的都是同一个结点，只需要遍历一遍链表修改prev链接域。链表的排序方法依然是以上两种，只考虑通过调整链接实现插入排序，操作过程就是一个个取下链接结点，将其插入一段元素递增的结点链中的正确位置。对于链接表，改变其中元素顺序的方法有两种：1.在结点之间搬动元素；2.修改结点之间的链接，改变结点的链接顺序。将单链表的排序复用到双链表上，最后遍历一遍链表修改prev链接域即可，不再赘述。]]></description><category></category></item><item><title><![CDATA[《Effective Java》第1条：用静态工厂方法代替构造器]]></title><link>https://blog.youkuaiyun.com/neOO0/article/details/133839862</link><guid>https://blog.youkuaiyun.com/neOO0/article/details/133839862</guid><author>neOO0</author><pubDate>Sun, 15 Oct 2023 15:45:17 +0800</pubDate><description><![CDATA[③可以直接通过接口引用被返回的对象。实现一个Book类，对于正在打折的书可以调用getSaledBook方法获取SaledBook实例，①能够实现SaledBook类的隐藏，②不需要知道SaledBook类的存在，通过Book即可调用。2. 不必每次调用的时候都创建一个新对象，可以使用预先构建好的实例，或者复用构建好的实例，能够：①避免创建不必要的重复对象；4. 所返回的对象的类可以随着每次调用而发生变化，这取决于静态工厂方法的参数值，客户端不知道也不需要知道它们从工厂方法中得到的对象的类。]]></description><category></category></item><item><title><![CDATA[链表的变形]]></title><link>https://blog.youkuaiyun.com/neOO0/article/details/133828524</link><guid>https://blog.youkuaiyun.com/neOO0/article/details/133828524</guid><author>neOO0</author><pubDate>Sat, 14 Oct 2023 21:08:24 +0800</pubDate><description><![CDATA[双链表可以变形为循环双链表，表尾结点next指向首结点，表首结点prev指向尾结点，与循环单链表需要掌握尾结点tail不同的是，循环双链表无论是掌握首结点head还是尾结点tail，都可以高效实现首尾两端的插入/删除操作，不再赘述。单链表的另一类常见变形是循环单链表，最后一个结点的引用域不为空(null)，而是指向首结点，表对象只需要一个数据域rear来引用尾结点，从而高效实现首尾两端的插入/删除操作。简单单链表的实现有一个缺点：尾端插入元素操作的效率很低。为了支持两端的高效操作，可以使用双引用域。]]></description><category></category></item><item><title><![CDATA[单链表的简单实现]]></title><link>https://blog.youkuaiyun.com/neOO0/article/details/133822714</link><guid>https://blog.youkuaiyun.com/neOO0/article/details/133822714</guid><author>neOO0</author><pubDate>Sat, 14 Oct 2023 11:22:41 +0800</pubDate><description><![CDATA[n个结点通过链接形成一条链接链，head变量用于保存表首结点的引用，称为表头变量或者表头指针，表尾结点的链接域置为空(null)，用于表示链表的结束。表元素域elem保存着作为一个表元素的数据项，链接域next里保存着同一个表里的下一个结点的链接。实现线性表的另一种常用技术是基于链接结构，用链接关系显式地表现元素之间的顺序关联。]]></description><category></category></item><item><title><![CDATA[动态顺序表的简单实现]]></title><link>https://blog.youkuaiyun.com/neOO0/article/details/133817644</link><guid>https://blog.youkuaiyun.com/neOO0/article/details/133817644</guid><author>neOO0</author><pubDate>Fri, 13 Oct 2023 20:51:18 +0800</pubDate><description><![CDATA[表中元素顺序存放在一大块连续存储区里，这样实现的表称为顺序表，在这种实现中，元素的顺序关系由存储位置的顺序表示。分离式带来的最大优势：存储区扩容。优点：O(1)时间的查询操作。怎么选择新存储区的容量呢？简单实现一个动态线性表。]]></description><category></category></item><item><title><![CDATA[表抽象数据类型]]></title><link>https://blog.youkuaiyun.com/neOO0/article/details/133817391</link><guid>https://blog.youkuaiyun.com/neOO0/article/details/133817391</guid><author>neOO0</author><pubDate>Fri, 13 Oct 2023 20:09:02 +0800</pubDate><description><![CDATA[两种基本实现模型：顺序表和链接表。]]></description><category></category></item></channel></rss>