<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Han1254</title>
  
  <subtitle>走在成为极客的路上。</subtitle>
  <link href="/atom.xml" rel="self"/>
  
  <link href="http://yoursite.com/"/>
  <updated>2019-08-31T04:28:56.402Z</updated>
  <id>http://yoursite.com/</id>
  
  <author>
    <name>Han1254</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>搜索-DFS</title>
    <link href="http://yoursite.com/2019/08/31/%E6%90%9C%E7%B4%A2-DFS/"/>
    <id>http://yoursite.com/2019/08/31/搜索-DFS/</id>
    <published>2019-08-31T03:30:09.000Z</published>
    <updated>2019-08-31T04:28:56.402Z</updated>
    
    <content type="html"><![CDATA[<p>实践是检验真理的唯一标准，一个算法最好是通过题目去理解  </p><p><strong><a href="https://pintia.cn/problem-sets/994805342720868352/problems/994805523835109376" target="_blank" rel="noopener">PAT (Advanced Level) Practice-1003 Emergency (25 分)</a></strong></p><a id="more"></a><h2 id="题目要求"><a href="#题目要求" class="headerlink" title="题目要求"></a>题目要求</h2><blockquote><p>As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.<br>(作为一个城市救援队的领导，你拥有一张特殊的城市地图。这张地图展示了几个零落的由道路连接的城市。每个城市救援队的数量以及两个城市之间的道路长度都被标出。当紧急情况发生时，你的工作就是要决定如何尽快地领导自己的队伍前往事发地点，而且要尽可能多地聚集每个结点的帮手)</p></blockquote><h2 id="Input-Specification"><a href="#Input-Specification" class="headerlink" title="Input Specification:"></a><strong>Input Specification:</strong></h2><blockquote><p>Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (≤500) - the number of cities (and the cities are numbered from 0 to N−1), M - the number of roads, C​1 and C​2<br>​​  - the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c1, c2<br>​​ and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C1 to C​2<br>​​ .</p></blockquote><h2 id="Output-Specification"><a href="#Output-Specification" class="headerlink" title="Output Specification:"></a><strong>Output Specification:</strong></h2><blockquote><p>For each test case, print in one line two numbers: the number of different shortest paths between C1 and C2<br>​​ , and the maximum amount of rescue teams you can possibly gather. All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.  </p></blockquote><h2 id="Sample-Input"><a href="#Sample-Input" class="headerlink" title="Sample Input:"></a><strong>Sample Input:</strong></h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">5 6 0 2</span><br><span class="line">1 2 1 5 3</span><br><span class="line">0 1 1</span><br><span class="line">0 2 2</span><br><span class="line">0 3 1</span><br><span class="line">1 2 1</span><br><span class="line">2 4 1</span><br><span class="line">3 4 1</span><br></pre></td></tr></table></figure><h2 id="Sample-Output"><a href="#Sample-Output" class="headerlink" title="Sample Output:"></a><strong>Sample Output:</strong></h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">2 4</span><br></pre></td></tr></table></figure><p>这是一个很典型的搜索问题，通过搜索，获得最短边权和以及最大点权和。<br>这就引出了我们接下来的算法  </p><h2 id="–DFS–深度优先搜索"><a href="#–DFS–深度优先搜索" class="headerlink" title="–DFS–深度优先搜索"></a><strong>–DFS–深度优先搜索</strong></h2><h3 id="这算法的主要思想是啥呢？"><a href="#这算法的主要思想是啥呢？" class="headerlink" title="这算法的主要思想是啥呢？"></a>这算法的主要思想是啥呢？</h3><ul><li>首先，我们需要得到一个地图，记录这某些对点之间的距离（当然也有可能记录着每个点的权重)，以及定义一个最短路径当作全局的一种变量（<font color="yellow">初始值一般是无穷大</font>)。</li><li>其次，我们需要一个起始点和一个终点，以及一个表，记录某条路是否走过。</li><li>最后，从起点开始，遍历其他的点，比如我们从0这个城市开始，想去4这个城市，接下来我们看看0-&gt;1，那么这个0-&gt;1这个路径就要被标记为已经走过，然后又递归进入本函数，一直递归递归，1-&gt;2, 2-&gt;6……直到递归到起点是我们之前的目的地，那么接下来我们就可以判断了，如果这条路径的总长度小于之前定义的最短路径，那么我们就将最短路径更新为这个新值（<font color="yellow">因为初始值一般定义为无穷大，所以第一次遍历时一定会更新</font>)，到了最后一步，开始return,一层一层地return，直到回到最初的起点，每一层在获得前一层的return后就要进行下一步，<font color="red"><strong>把之前标记为已经走过的道路再重新标记为没走过</strong></font>，这个是很重要的，因为我们的目的不是要标记路走没走过，目的是为了更新最短路径。那么在接下来的搜索中，如果当前的路程已经大于之前更新过的最短路径了，那就啥都憋suo了~，return就完了</li></ul><h3 id="针对这个题目，我们可以先看看怎么解"><a href="#针对这个题目，我们可以先看看怎么解" class="headerlink" title="针对这个题目，我们可以先看看怎么解"></a>针对这个题目，我们可以先看看怎么解</h3><p><strong>上代码</strong> <font color="gree"> (ﾉ◕ヮ◕)ﾉ:･*ﾟ✧ </font><br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> 最短路径;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.nio.file.Path;</span><br><span class="line"><span class="keyword">import</span> java.sql.SQLNonTransientConnectionException;</span><br><span class="line"><span class="keyword">import</span> java.util.Scanner;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">DFS</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int</span> n = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int</span> m = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int</span> c1 = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int</span> c2 = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int</span>[][] map = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">500</span>][<span class="number">500</span>];</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int</span>[] weight = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">500</span>];</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">boolean</span>[][] visit = <span class="keyword">new</span> <span class="keyword">boolean</span>[<span class="number">500</span>][<span class="number">500</span>];</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> totalPath = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> totalWehght = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> minPath = Integer.MAX_VALUE;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    Scanner scanner = <span class="keyword">new</span> Scanner(System.in);</span><br><span class="line">    n = scanner.nextInt();</span><br><span class="line">    m = scanner.nextInt();</span><br><span class="line">    c1 = scanner.nextInt();</span><br><span class="line">    c2 = scanner.nextInt();</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">    weight[i] = scanner.nextInt();</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; m; i++) &#123;</span><br><span class="line">    <span class="keyword">int</span> x = scanner.nextInt();</span><br><span class="line">    <span class="keyword">int</span> y = scanner.nextInt();</span><br><span class="line">    <span class="keyword">int</span> z = scanner.nextInt();</span><br><span class="line">    map[x][y] = map[y][x] = z;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(c1, <span class="number">0</span>, weight[c1]);</span><br><span class="line">    System.out.println(totalPath+<span class="string">" "</span>+totalWehght);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//这个算法就是整个解题的灵魂</span></span><br><span class="line">    <span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> start, <span class="keyword">int</span> Lpath, <span class="keyword">int</span> weights)</span> </span>&#123;</span><br><span class="line">        <span class="comment">//判断如果到达了终点</span></span><br><span class="line">    <span class="keyword">if</span>(start == c2) &#123;</span><br><span class="line">    <span class="keyword">if</span>(Lpath &lt; minPath) &#123;</span><br><span class="line">                <span class="comment">//突然发现这个路径的长度比上一次更新的还短，那就把最短路径的个数更新为1</span></span><br><span class="line">    totalPath = <span class="number">1</span>;</span><br><span class="line">    minPath = Lpath;</span><br><span class="line">    totalWehght = weights;</span><br><span class="line">    &#125;<span class="keyword">else</span> <span class="keyword">if</span>(Lpath == minPath) &#123;</span><br><span class="line">                <span class="comment">//突然发现最短路径跟上次一样，这两条路径在长度上是等价的，加上这个路径</span></span><br><span class="line">    totalPath++;</span><br><span class="line">    <span class="keyword">if</span>(totalWehght &lt; weights) &#123;</span><br><span class="line">    totalWehght = weights;</span><br><span class="line">    &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">if</span>(Lpath &gt; minPath) &#123;</span><br><span class="line">            <span class="comment">//不管你运行到哪个结点了，只要发现你的路径长度比上一次更新过的长，直接就别往下走了</span></span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            <span class="comment">//从起点（每一次循环的起点，你这次的终点就是下一次的起点）开始遍历其他的没有走过的点，并且起点与该点之间的距离不能为零</span></span><br><span class="line">    <span class="keyword">if</span>(!visit[start][i] &amp;&amp; map[start][i] != <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="comment">//先把这个路径设为已经走过了</span></span><br><span class="line">    visit[start][i] = visit[i][start] = <span class="keyword">true</span>;</span><br><span class="line">                <span class="comment">//开始递归，把这次的终点当作下次的起点，计算新的路径长度，计算新的点权重和</span></span><br><span class="line">    dfs(i, Lpath + map[start][i], weights + weight[i]);</span><br><span class="line">                <span class="comment">//上面这个递归结束了，那就把之间的标记给去掉</span></span><br><span class="line">    visit[start][i] = visit[i][start] = <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//相信你通过这个题应该就能大体上看懂了DFS算法了</span></span><br></pre></td></tr></table></figure></p><h3 id="总结："><a href="#总结：" class="headerlink" title="总结："></a>总结：</h3><ul><li>其实也不是特别难懂</li><li>算法很精妙</li><li>时间复杂度应该是O(n^2),还不是特别恐怖。</li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;实践是检验真理的唯一标准，一个算法最好是通过题目去理解  &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://pintia.cn/problem-sets/994805342720868352/problems/994805523835109376&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;PAT (Advanced Level) Practice-1003 Emergency (25 分)&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="算法" scheme="http://yoursite.com/categories/%E7%AE%97%E6%B3%95/"/>
    
      <category term="搜索" scheme="http://yoursite.com/categories/%E7%AE%97%E6%B3%95/%E6%90%9C%E7%B4%A2/"/>
    
    
      <category term="Java" scheme="http://yoursite.com/tags/Java/"/>
    
      <category term="pta" scheme="http://yoursite.com/tags/pta/"/>
    
  </entry>
  
  <entry>
    <title>leetcode—_两数相加</title>
    <link href="http://yoursite.com/2019/08/27/leetcode%E2%80%94-%E4%B8%A4%E6%95%B0%E7%9B%B8%E5%8A%A0/"/>
    <id>http://yoursite.com/2019/08/27/leetcode—-两数相加/</id>
    <published>2019-08-27T12:53:26.000Z</published>
    <updated>2019-08-28T06:19:29.747Z</updated>
    
    <content type="html"><![CDATA[<p><em>链表是数据结构中比较重要的一个知识点，结合leetcode的第二题-两数相加来看看链表的实现。</em></p><a id="more"></a><p><a href="https://www.jianshu.com/p/a64d1ef95980" target="_blank" rel="noopener">一篇文章搞定面试中的链表题目(java实现)</a></p><p><a href="https://blog.csdn.net/xh13007612005/article/details/77161371" target="_blank" rel="noopener">Java实现单链表的插入、删除、计算链表的长度和输出链表</a></p><p>链表顾名思义就是一种带链子的表，一环扣一环。每一个环节都可分成两个部分，一部分是数据，一部分是指向下一个环节的指针。</p><h2 id="如果要定义一个链表环节可以这么做"><a href="#如果要定义一个链表环节可以这么做" class="headerlink" title="如果要定义一个链表环节可以这么做"></a>如果要定义一个链表环节可以这么做</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ListNode</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> data;<span class="comment">//data就是每个环节所存储的数据</span></span><br><span class="line">ListNode next = <span class="keyword">null</span>;<span class="comment">//next用来储存下一个环节的地址</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span>  <span class="title">ListNode</span><span class="params">(<span class="keyword">int</span> data)</span> </span>&#123;</span><br><span class="line"><span class="keyword">this</span>.data = data;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="当我们使用的时候，可以这样"><a href="#当我们使用的时候，可以这样" class="headerlink" title="当我们使用的时候，可以这样"></a>当我们使用的时候，可以这样</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">Main myMain = <span class="keyword">new</span> Main();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">ListNode l1 = <span class="keyword">null</span>;</span><br><span class="line">l1 = myMain.insertNode(<span class="number">1</span>, l1);</span><br><span class="line">myMain.insertNode(<span class="number">2</span>, l1);</span><br><span class="line">myMain.insertNode(<span class="number">3</span>, l1);</span><br><span class="line"></span><br><span class="line">ListNode l2 = <span class="keyword">null</span>;</span><br><span class="line">l2 = myMain.insertNode(<span class="number">1</span>, l2);</span><br><span class="line">myMain.insertNode(<span class="number">2</span>, l2);</span><br><span class="line">myMain.insertNode(<span class="number">3</span>, l2);</span><br><span class="line"></span><br><span class="line">ListNode node = myMain.addTowNode(l1, l2);</span><br><span class="line">myMain.printNodelist(node);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//这个方法是用来循环打印数据</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">printNodelist</span><span class="params">(ListNode listNode)</span> </span>&#123;</span><br><span class="line">ListNode node = listNode;</span><br><span class="line"><span class="keyword">while</span>(node != <span class="keyword">null</span>) &#123;</span><br><span class="line">System.out.print(node.data+<span class="string">" "</span>);</span><br><span class="line">node = node.next;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">System.out.println();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//往链表中插入数据</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> ListNode <span class="title">insertNode</span><span class="params">(<span class="keyword">int</span> data, ListNode node)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">ListNode head = <span class="keyword">new</span> ListNode(data);</span><br><span class="line"><span class="keyword">if</span>(node == <span class="keyword">null</span>) &#123;</span><br><span class="line">node = head;</span><br><span class="line"><span class="keyword">return</span> node;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">ListNode temp = node;</span><br><span class="line"><span class="keyword">while</span>(temp.next != <span class="keyword">null</span>) &#123;</span><br><span class="line">temp = temp.next;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">temp.next = head;</span><br><span class="line"><span class="keyword">return</span> node;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//将两个链表的每个数据进行相加</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> ListNode <span class="title">addTowNode</span><span class="params">(ListNode l1, ListNode l2)</span> </span>&#123;</span><br><span class="line">ListNode p = l1;</span><br><span class="line">ListNode q = l2;</span><br><span class="line">ListNode head = <span class="keyword">null</span>;</span><br><span class="line"><span class="keyword">int</span> carry = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">while</span>(p != <span class="keyword">null</span> || q != <span class="keyword">null</span>) &#123;</span><br><span class="line"><span class="keyword">int</span> x = (p != <span class="keyword">null</span>)?p.data:<span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> y = (q != <span class="keyword">null</span>)?q.data:<span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> sum = x + y;</span><br><span class="line">head = insertNode(sum % <span class="number">10</span>, head);</span><br><span class="line">carry = sum / <span class="number">10</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(p != <span class="keyword">null</span>) &#123;</span><br><span class="line">p = p.next;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (q != <span class="keyword">null</span>) &#123;</span><br><span class="line">q = q.next;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(carry &gt; <span class="number">0</span>) &#123;</span><br><span class="line">head.next = <span class="keyword">new</span> ListNode(carry);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> head;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="在leetcode中的题目是这样要求的："><a href="#在leetcode中的题目是这样要求的：" class="headerlink" title="在leetcode中的题目是这样要求的："></a>在leetcode中的题目是这样要求的：</h2><blockquote><p>给出两个 非空 的链表用来表示两个非负的整数。其中，它们各自的位数是按照 逆序 的方式存储的，并且它们的每个节点只能存储 一位 数字。<br>如果，我们将这两个数相加起来，则会返回一个新的链表来表示它们的和。</p></blockquote><blockquote><p>您可以假设除了数字 0 之外，这两个数都不会以 0 开头。</p></blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">输入：(2 -&gt; 4 -&gt; 3) + (5 -&gt; 6 -&gt; 4)</span><br><span class="line">输出：7 -&gt; 0 -&gt; 8</span><br><span class="line">原因：342 + 465 = 807</span><br></pre></td></tr></table></figure><h2 id="看看我这修改了无数遍的答案"><a href="#看看我这修改了无数遍的答案" class="headerlink" title="看看我这修改了无数遍的答案"></a>看看我这修改了无数遍的答案</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * public class ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) &#123; val = x; &#125;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line"><span class="comment">//    public static ListNode insertNode(int data, ListNode node) &#123;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// ListNode head = new ListNode(data);</span></span><br><span class="line"><span class="comment">// if(node == null) &#123;</span></span><br><span class="line"><span class="comment">// node = head;</span></span><br><span class="line"><span class="comment">// return node;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// ListNode temp = node;</span></span><br><span class="line"><span class="comment">// while(temp.next != null) &#123;</span></span><br><span class="line"><span class="comment">// temp = temp.next;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// temp.next = head;</span></span><br><span class="line"><span class="comment">// return node;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span>  ListNode <span class="title">addTwoNumbers</span><span class="params">(ListNode l1, ListNode l2)</span> </span>&#123;</span><br><span class="line">ListNode p = l1;</span><br><span class="line">ListNode q = l2;</span><br><span class="line">ListNode head = <span class="keyword">new</span> ListNode(<span class="number">0</span>);<span class="comment">//这里使用了哑节点，不需要判断空值情况</span></span><br><span class="line">         ListNode curr = head;</span><br><span class="line"><span class="keyword">int</span> carry = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">while</span>(p != <span class="keyword">null</span> || q != <span class="keyword">null</span>) &#123;</span><br><span class="line"><span class="keyword">int</span> x = (p != <span class="keyword">null</span>)?p.val:<span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> y = (q != <span class="keyword">null</span>)?q.val:<span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> sum = x + y + carry;</span><br><span class="line"><span class="comment">// head = insertNode(sum % 10, head);</span></span><br><span class="line">            </span><br><span class="line">           </span><br><span class="line"><span class="comment">//             if(curr == null)&#123;</span></span><br><span class="line"><span class="comment">//                 curr = new ListNode(sum % 10);</span></span><br><span class="line"><span class="comment">//             &#125;else&#123;</span></span><br><span class="line"><span class="comment">//                 curr.next = new ListNode(sum % 10);</span></span><br><span class="line"><span class="comment">//                 curr = curr.next;</span></span><br><span class="line"><span class="comment">//             &#125;</span></span><br><span class="line">           curr.next = <span class="keyword">new</span> ListNode(sum % <span class="number">10</span>);</span><br><span class="line">            curr = curr.next;</span><br><span class="line">            </span><br><span class="line">            </span><br><span class="line">carry = sum / <span class="number">10</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(p != <span class="keyword">null</span>) &#123;</span><br><span class="line">p = p.next;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (q != <span class="keyword">null</span>) &#123;</span><br><span class="line">q = q.next;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(carry &gt; <span class="number">0</span>) &#123;</span><br><span class="line">curr.next = <span class="keyword">new</span> ListNode(carry);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> head.next;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="看看真正的哑结点的用法"><a href="#看看真正的哑结点的用法" class="headerlink" title="看看真正的哑结点的用法"></a>看看真正的哑结点的用法</h2><p><a href="https://blog.csdn.net/x55x5/article/details/82493185" target="_blank" rel="noopener">链表 - 哑节点</a></p><h3 id="定义结构体"><a href="#定义结构体" class="headerlink" title="定义结构体"></a>定义结构体</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ListNode</span> &#123;</span></span><br><span class="line">    <span class="keyword">int</span> val;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">ListNode</span> *<span class="title">next</span>;</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h3 id="如果引入了哑节点的，函数就可以得到简化，"><a href="#如果引入了哑节点的，函数就可以得到简化，" class="headerlink" title="如果引入了哑节点的，函数就可以得到简化，"></a>如果引入了哑节点的，函数就可以得到简化，</h3><p>在调用addNode()函数之前，我们先定义哑节点<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ListNode</span> *<span class="title">dummyNode</span>= (<span class="title">struct</span> <span class="title">ListNode</span>*) <span class="title">malloc</span>( <span class="title">sizeof</span>(<span class="title">struct</span> <span class="title">ListNode</span>)  );</span></span><br><span class="line">dummyNode-&gt;val = null;</span><br><span class="line">dummyNode-&gt;next = null;</span><br></pre></td></tr></table></figure></p><h3 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">ListNode *<span class="title">addNode</span><span class="params">( ListNode *dummyNode, <span class="keyword">int</span> num)</span></span>&#123;<span class="comment">// 函数返回的是尾节点</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">ListNode</span> *<span class="title">new</span> = (<span class="title">struct</span> <span class="title">ListNode</span>*) <span class="title">malloc</span>( <span class="title">sizeof</span>(<span class="title">struct</span> <span class="title">ListNode</span>) * <span class="title">num</span> );</span></span><br><span class="line">    <span class="comment">/* 此处不再需要处理头节点为空的情况，因为dummyNode一定非空 */</span></span><br><span class="line">    dummyNode-&gt;next = <span class="keyword">new</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;em&gt;链表是数据结构中比较重要的一个知识点，结合leetcode的第二题-两数相加来看看链表的实现。&lt;/em&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Leetcode" scheme="http://yoursite.com/categories/Leetcode/"/>
    
      <category term="链表" scheme="http://yoursite.com/categories/Leetcode/%E9%93%BE%E8%A1%A8/"/>
    
    
      <category term="Java" scheme="http://yoursite.com/tags/Java/"/>
    
      <category term="leetcode" scheme="http://yoursite.com/tags/leetcode/"/>
    
  </entry>
  
  <entry>
    <title>Paging框架</title>
    <link href="http://yoursite.com/2019/08/11/Paging%E6%A1%86%E6%9E%B6/"/>
    <id>http://yoursite.com/2019/08/11/Paging框架/</id>
    <published>2019-08-11T11:30:34.000Z</published>
    <updated>2019-08-11T11:47:01.335Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Paging学习"><a href="#Paging学习" class="headerlink" title="Paging学习"></a>Paging学习</h1><blockquote><p>Paging是Google 2018 IO大会最新发布的Jetpack中的一个组件，主要用于大数据的分页加载<br><a id="more"></a>  </p></blockquote><h2 id="需要补充的知识"><a href="#需要补充的知识" class="headerlink" title="需要补充的知识"></a>需要补充的知识</h2><ul><li><p>接口回调<br><a href="https://blog.csdn.net/u011555996/article/details/85327411" target="_blank" rel="noopener">通过点击事件监听 setOnClickListener 彻底理解回调-Android</a></p></li><li><p>Room<br><a href="https://blog.csdn.net/etwge/article/details/80831183" target="_blank" rel="noopener">Android Room的详细介绍</a></p><p><a href="https://blog.csdn.net/qq_21793463/article/details/78905316" target="_blank" rel="noopener">Android架构组件Room的使用</a>(适合进阶)  </p></li><li><p>Java注解和反射<br><a href="https://juejin.im/post/5b45bd715188251b3a1db54f" target="_blank" rel="noopener">JAVA 注解的基本原理</a><br><a href="https://juejin.im/post/598ea9116fb9a03c335a99a4" target="_blank" rel="noopener">Java 反射由浅入深 | 进阶必备</a><br><a href="https://blog.csdn.net/WSDS_MZM/article/details/77675777" target="_blank" rel="noopener">Java反射（包含getMethod以及invoke）</a><br><a href="https://www.jianshu.com/p/097e574e36b0" target="_blank" rel="noopener">搞定代理模式,看懂Retrofit动态代理的骚操作</a></p></li><li><p>LiveData<br><a href="https://www.jianshu.com/p/87aa6464412b" target="_blank" rel="noopener">Android应用结构之LiveData</a></p></li><li>ViewModel</li><li>RxJava<br><a href="https://www.jianshu.com/p/0cd258eecf60" target="_blank" rel="noopener">这可能是最好的RxJava 2.x 教程（完结版）</a></li></ul><h2 id="我的理解"><a href="#我的理解" class="headerlink" title="我的理解"></a>我的理解</h2><p>首先来说，paging框架应该分成三部分：<strong>Data</strong>, <strong>ViewModel</strong>, <strong>UI</strong></p><h3 id="Data"><a href="#Data" class="headerlink" title="Data"></a>Data</h3><ul><li>Data是数据的提供者，数据的来源可以是后端返回数据，也可以是Room数据库存贮，当然也可以是本地数据。</li><li>Data可以分成两部分：DataSource和DataSourceFactory。DataSourceFactory继承DataSource.Factory,<strong>是用来创建DataSource的途径。</strong><ul><li><strong>DataSource</strong> </li></ul></li></ul><p>  <a href="https://www.jianshu.com/p/fd00c0fbd774" target="_blank" rel="noopener">和page相关的3种DataSource的区别</a><br>  <a href="http://www.jintiankansha.me/t/FllXM5oeGK" target="_blank" rel="noopener">Android Paging分页组件的使用及原理</a><br>  <a href="https://juejin.im/entry/57c8e05ca633bd006c03bfed" target="_blank" rel="noopener">我所理解的 RxJava——上手其实很简单（二）(publishSubject的使用)</a><br>  <a href="https://juejin.im/post/5a68c51e518825734f52e2dc" target="_blank" rel="noopener">大话Android多线程(一) Thread和Runnable的联系和区别</a><br><a href="https://juejin.im/entry/5763b1e1d342d30058de759e" target="_blank" rel="noopener">30 分钟入门 Java8 之 lambda 表达式</a></p><ol><li>DataSource可以利用Retrofit等方式，通过传入代理类进行数据请求，将数据返回到被观察的LiveData中。</li><li><font color="red"><strong>设置可取消类Disposable,防止内存泄漏???????</strong></font></li><li>PositionalDataSource中需要实现两种方法：LoadInitial, LoadRange.进行数据请求时<font color="orange"><strong>代理类</strong></font>中的参数有：<font color="orange"><strong>初始请求的数据位置(startpostion)，每次请求的页数(pagesize), PagaingCallback接口实例（这个是自定义的）</strong></font>  </li><li><p>无论是LoadInitial还是LoadRange,方法参数都有callback, callback都有一个方法onResult(List&lt;&gt;), 调用这个方法，便可将数据传送到被观察的数据中。</p><ol start="5"><li>与此同时，在请求前，请求成功以及请求失败时，都应更新ViewModel对应的网络状态。</li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"> </span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">PagingDataSource</span>&lt;<span class="title">T</span>&gt; <span class="keyword">extends</span> <span class="title">PositionalDataSource</span>&lt;<span class="title">T</span>&gt; <span class="keyword">implements</span> <span class="title">DataSource</span>.<span class="title">InvalidatedCallback</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">private</span> Runnable mRetry;</span><br><span class="line">  <span class="keyword">private</span> PagingViewModel&lt;T&gt; mViewModel;</span><br><span class="line">  <span class="keyword">private</span> PagingRepository mApi;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">private</span> <span class="keyword">final</span> CompositeDisposable mDisposable = <span class="keyword">new</span> CompositeDisposable();</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="title">PagingDataSource</span><span class="params">(PagingViewModel&lt;T&gt; viewModel, PagingRepository api)</span> </span>&#123;</span><br><span class="line">      <span class="keyword">this</span>.mViewModel = viewModel;</span><br><span class="line">      <span class="keyword">this</span>.mApi = api;</span><br><span class="line"></span><br><span class="line">     <span class="comment">//registerRetry返回的是一个publishSubject,可以用来简化订阅过程</span></span><br><span class="line">      register(mViewModel.registerRetry().subscribe(s -&gt; &#123;</span><br><span class="line">          <span class="keyword">if</span> (mRetry != <span class="keyword">null</span>) &#123;</span><br><span class="line">              mRetry.run();</span><br><span class="line">              mRetry = <span class="keyword">null</span>;</span><br><span class="line">          &#125;</span><br><span class="line">      &#125;, Throwable::printStackTrace));<span class="comment">//这里mViewModel正式被一个线程订阅，检测其变化？？？？？？？？？？？？？？？？？</span></span><br><span class="line"></span><br><span class="line">      <span class="comment">//这个额。为啥一定要出现？？？？？？？？？？？？</span></span><br><span class="line">      addInvalidatedCallback(<span class="keyword">this</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//防止出现内存泄漏</span></span><br><span class="line">  <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">register</span><span class="params">(Disposable disposable)</span> </span>&#123;</span><br><span class="line">      mDisposable.add(disposable);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">loadInitial</span><span class="params">(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback&lt;T&gt; callback)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//更新mViewModel里的网络状态量</span></span><br><span class="line">      mViewModel.getRefreshState().postValue(NetworkStatus.loading());</span><br><span class="line"></span><br><span class="line">    <span class="comment">//这里请求的过程后面会重写</span></span><br><span class="line">      mApi.getDataList(<span class="number">0</span>, PagingViewModel.INIT_LOAD_SIZE, <span class="keyword">new</span> PagingCallBack() &#123;</span><br><span class="line">          <span class="meta">@Override</span></span><br><span class="line">          <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onSuccess</span><span class="params">(List list)</span> </span>&#123;</span><br><span class="line">            <span class="comment">//更新网络状态</span></span><br><span class="line">        mViewModel.getRefreshState().postValue(NetworkStatus.success())；</span><br><span class="line"></span><br><span class="line">        <span class="comment">//设置hasMore里持有量为true，说明还有更多的数据</span></span><br><span class="line">              mViewModel.hasMore().postValue(<span class="keyword">true</span>);</span><br><span class="line">              <span class="keyword">if</span> (isEmptyList(list)) &#123;</span><br><span class="line">                <span class="comment">//onResult方法会将数据直接发送到检测这个LiveData的UI进程中。</span></span><br><span class="line">                  callback.onResult(<span class="keyword">new</span> ArrayList&lt;&gt;(), <span class="number">0</span>);</span><br><span class="line">              &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                  callback.onResult(<span class="keyword">new</span> ArrayList(list), <span class="number">0</span>);</span><br><span class="line">              &#125;</span><br><span class="line">          &#125;</span><br><span class="line"></span><br><span class="line">          <span class="meta">@Override</span></span><br><span class="line">          <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onError</span><span class="params">(Exception e)</span> </span>&#123;</span><br><span class="line">              mViewModel.getRefreshState().postValue(NetworkStatus.error());</span><br><span class="line">              <span class="comment">//重新进行初始化数据请求</span></span><br><span class="line">              mRetry = () -&gt; loadInitial(params, callback);</span><br><span class="line">          &#125;</span><br><span class="line">      &#125;);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">loadRange</span><span class="params">(@NonNull LoadRangeParams params, @NonNull LoadRangeCallback&lt;T&gt; callback)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">      mViewModel.getLoadingState().postValue(NetworkStatus.loading());</span><br><span class="line">      mApi.getDataList(params.startPosition, PagingViewModel.PAGE_SIZE, <span class="keyword">new</span> PagingCallBack() &#123;</span><br><span class="line">          <span class="meta">@Override</span></span><br><span class="line">          <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onSuccess</span><span class="params">(List list)</span> </span>&#123;</span><br><span class="line">              mViewModel.getLoadingState().postValue(NetworkStatus.success());</span><br><span class="line">              <span class="keyword">if</span> (isEmptyList(list)) &#123;</span><br><span class="line">                  callback.onResult(<span class="keyword">new</span> ArrayList&lt;&gt;());</span><br><span class="line">              &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                  callback.onResult(list);</span><br><span class="line">              &#125;</span><br><span class="line">          &#125;</span><br><span class="line"></span><br><span class="line">          <span class="meta">@Override</span></span><br><span class="line">          <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onError</span><span class="params">(Exception e)</span> </span>&#123;</span><br><span class="line">              mViewModel.getLoadingState().postValue(NetworkStatus.error());</span><br><span class="line">              mRetry = () -&gt; loadRange(params, callback);</span><br><span class="line">          &#125;</span><br><span class="line">      &#125;);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="keyword">private</span> <span class="keyword">boolean</span> <span class="title">isEmptyList</span><span class="params">(List list)</span> </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> list == <span class="keyword">null</span> || list.isEmpty();</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//这个应该是取消订阅或者销毁线程的时候用到的，不用太管它</span></span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onInvalidated</span><span class="params">()</span> </span>&#123;</span><br><span class="line">      removeInvalidatedCallback(<span class="keyword">this</span>);</span><br><span class="line">      mDisposable.clear();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ol><ul><li><strong>DataSourceFactory</strong></li></ul><ol><li>这个就很简单了，创建一个<code>Multabel&lt;DataSource&gt;</code>, 创建构造方法，重写create方法，这个会在接下来的ViewModel中用到。<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">PagingDataSourceFactory</span>&lt;<span class="title">T</span>&gt; <span class="keyword">extends</span> <span class="title">DataSource</span>.<span class="title">Factory</span>&lt;<span class="title">Integer</span>, <span class="title">T</span>&gt; </span>&#123;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> MutableLiveData&lt;PagingDataSource&lt;T&gt;&gt; mDataSource = <span class="keyword">new</span> MutableLiveData&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">PagingDataSourceFactory</span><span class="params">(PagingDataSource&lt;T&gt; dataSource)</span> </span>&#123;</span><br><span class="line">        mDataSource.setValue(dataSource);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> DataSource&lt;Integer, T&gt; <span class="title">create</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> mDataSource.getValue();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> MutableLiveData&lt;PagingDataSource&lt;T&gt;&gt; getDataSource() &#123;</span><br><span class="line">        <span class="keyword">return</span> mDataSource;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ol><h3 id="ViewModel"><a href="#ViewModel" class="headerlink" title="ViewModel"></a><strong>ViewModel</strong></h3><ul><li><p>如果说Data部分是数据的储藏车间，那么viewmodel进行的工作就是将数据按照特定的格式，每次定量地从车间搬运，从而在UI上显示数据的更新。</p><ul><li><strong>PagingViewModel(extends ViewModel)</strong><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br></pre></td><td class="code"><pre><span class="line">  <span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">PagingViewModel</span>&lt;<span class="title">T</span>&gt; <span class="keyword">extends</span> <span class="title">ViewModel</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">   <span class="comment">//设置初始化请求量</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> INIT_LOAD_SIZE = <span class="number">20</span>;</span><br><span class="line">   <span class="comment">//设置请求页数</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> PAGE_SIZE = <span class="number">20</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> LiveData&lt;PagedList&lt;T&gt;&gt; mDataList;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> MutableLiveData&lt;NetworkStatus&gt; mRefreshState = <span class="keyword">new</span> MutableLiveData&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">protected</span> MutableLiveData&lt;NetworkStatus&gt; mLoadingState = <span class="keyword">new</span> MutableLiveData&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">protected</span> MutableLiveData&lt;Boolean&gt; isEmpty = <span class="keyword">new</span> MutableLiveData&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">protected</span> MutableLiveData&lt;Boolean&gt; hasMore = <span class="keyword">new</span> MutableLiveData&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> PublishSubject&lt;String&gt; retry = PublishSubject.create();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> PagingDataSourceFactory&lt;T&gt; mFactory;</span><br><span class="line"></span><br><span class="line">   <span class="comment">//初始化数据，得到一个包含DataSource的DataSourceFactory的实例</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">PagingViewModel</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (mDataList == <span class="keyword">null</span>) &#123;</span><br><span class="line">            mFactory = <span class="keyword">new</span> PagingDataSourceFactory&lt;&gt;(getDataSource());</span><br><span class="line">            mDataList = buildPagedList();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//这一步很重要，这一步直接将ViewModel与DataSourceFactory对接，从DataSourceFactory里面得到DataSource的实例，LivePagedListBuilder&lt;&gt;()方法  中需要传入的参数是继承Data.Factory的类和一个配置Config,getConfig是在下面自定义的方法，配置了PagedList.Config。最后返回的数据就是一个LiveData&lt;PgaedList&lt;T&gt;&gt;.</span></span><br><span class="line">    <span class="keyword">private</span> LiveData&lt;PagedList&lt;T&gt;&gt; buildPagedList() &#123;</span><br><span class="line">        isEmpty.setValue(<span class="keyword">false</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> LivePagedListBuilder&lt;&gt;(mFactory, getConfig())</span><br><span class="line">        <span class="comment">//setBoundaryCallback是在数据耗尽后进行的回调传参，其中PagingBoundaryCallback&lt;T&gt;为自定义类，继承自PagedList.BoundaryCallback&lt;T&gt;</span></span><br><span class="line">                .setBoundaryCallback(<span class="keyword">new</span> PagingBoundaryCallback&lt;&gt;(hasMore, isEmpty))</span><br><span class="line">                .build();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> LiveData&lt;PagedList&lt;T&gt;&gt; getDataList() &#123;</span><br><span class="line">        <span class="keyword">return</span> mDataList;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> MutableLiveData&lt;NetworkStatus&gt; <span class="title">getLoadingState</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> mLoadingState;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> MutableLiveData&lt;NetworkStatus&gt; <span class="title">getRefreshState</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> mRefreshState;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> MutableLiveData&lt;Boolean&gt; <span class="title">isEmpty</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> isEmpty;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> MutableLiveData&lt;Boolean&gt; <span class="title">hasMore</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> hasMore;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">   <span class="comment">//publishSubject可以当作一个observerble,发送消息("retry");</span></span><br><span class="line">   <span class="comment">//在PagingDataSource中被订阅</span></span><br><span class="line">   <span class="comment">//好吧这个我实在不知道他多此一举是为什么？？？？？？？？？？</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">retry</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        retry.onNext(<span class="string">"retry"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">refresh</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        mDataList = buildPagedList();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">showList</span><span class="params">(List&lt;T&gt; list)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(mDataList.getValue()!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            mDataList.getValue().clear();</span><br><span class="line">            mDataList.getValue().addAll(list);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> PublishSubject&lt;String&gt; <span class="title">registerRetry</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> retry;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> PagedList.<span class="function">Config <span class="title">getConfig</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> PagedList.Config.Builder()</span><br><span class="line">                <span class="comment">//配置分页加载的数量</span></span><br><span class="line">                .setPageSize(PAGE_SIZE)</span><br><span class="line">                <span class="comment">//配置是否启动PlaceHolders</span></span><br><span class="line">                .setEnablePlaceholders(<span class="keyword">false</span>)</span><br><span class="line">                <span class="comment">//初始化加载的数量</span></span><br><span class="line">                .setInitialLoadSizeHint(INIT_LOAD_SIZE)</span><br><span class="line">                .build();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//在后面继承PagingViewModel的类中具体实现，从而能够构造PagingDataSourceFactory</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">abstract</span> PagingDataSource&lt;T&gt; <span class="title">getDataSource</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ul></li><li><p><strong>PagingListAdapter</strong><br><a href="http://zh.lucida.me/blog/java-8-lambdas-insideout-language-features/" target="_blank" rel="noopener">深入理解Java 8 Lambda（语言篇——lambda，方法引用，目标类型和默认方法</a></p></li></ul><p><strong><font color="red">## 老铁顶住，我要放大招了：##</font></strong></p><h2 id="刺激不-（-๑乛◡乛๑-）（一点一点地看）"><a href="#刺激不-（-๑乛◡乛๑-）（一点一点地看）" class="headerlink" title="刺激不 （ ๑乛◡乛๑ ）（一点一点地看）"></a>刺激不 <font color="pink">（ ๑乛◡乛๑ ）</font>（一点一点地看）</h2><ul><li><p>首先我们先看adapter的构造方法</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="title">PagingListAdapter</span><span class="params">(@NonNull DiffUtil.ItemCallback&lt;T&gt; diffCallback,</span></span></span><br><span class="line"><span class="function"><span class="params">                             LifecycleOwner owner)</span> </span>&#123;</span><br><span class="line">     <span class="keyword">super</span>(diffCallback);</span><br><span class="line">     mLifecycleOwner = owner;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure><p>里面需要传入两个参数，一个是DiffUtil.ItemCallback, 一个是LifecycleOwner，DiffUtil.ItemCallback是在继承pagingListAdapter的类中根据实际情况实现的。</p><p>这个diffutil.itemcallback的传入是很讲究滴。 </p><p>在adapter构造完成后，传入一个已经写好的DiffUitl.ItemCallback实例，继续传入到AsyncPagedListDiffer中，最后一路传入PagedStorageHelper中。</p></li></ul><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="title">PagedListAdapter</span><span class="params">(@NonNull DiffUtil.ItemCallback&lt;T&gt; diffCallback)</span> </span>&#123;</span><br><span class="line">  <span class="comment">//这是PagedListAdapter的构造函数，调用了AsyncPagedListDiffer的构造函数</span></span><br><span class="line">        mDiffer = <span class="keyword">new</span> AsyncPagedListDiffer&lt;&gt;(<span class="keyword">this</span>, diffCallback);</span><br><span class="line">        mDiffer.mListener = mListener;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure><p> 而在adapter中可以调用一个submitList方法，如下图，调用了PagedListAdapter的submitList方法，从而调用了AsyncPagedListDiffer的submitList方法。</p> <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//AsyncPagedListDiff.java 149行 这个构造是从PagedListAdapter调过来的</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">AsyncPagedListDiffer</span><span class="params">(@NonNull RecyclerView.Adapter adapter,</span></span></span><br><span class="line"><span class="function"><span class="params">           @NonNull DiffUtil.ItemCallback&lt;T&gt; diffCallback)</span> </span>&#123;</span><br><span class="line">       mUpdateCallback = <span class="keyword">new</span> AdapterListUpdateCallback(adapter);</span><br><span class="line">       mConfig = <span class="keyword">new</span> AsyncDifferConfig.Builder&lt;T&gt;(diffCallback).build();</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//PagedListAdapter 150行</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">submitList</span><span class="params">(PagedList&lt;T&gt; pagedList)</span> </span>&#123;</span><br><span class="line">        mDiffer.submitList(pagedList);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure><p>在AsyncPagedListDiffer的submitList方法中，调用了PagedStorageDiffHelper的computeDiff方法，通过之前传入的回调实例，得到一个DiffResult.<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">//PagedStorageDiffHelper.java 37行 获取result</span></span><br><span class="line">&#123; </span><br><span class="line">  <span class="keyword">static</span> &lt;T&gt; DiffUtil.<span class="function">DiffResult <span class="title">computeDiff</span><span class="params">(······)</span></span></span><br><span class="line"><span class="function">          <span class="comment">//······//</span></span></span><br><span class="line"><span class="function">    return diffCallback.<span class="title">getChangePayload</span><span class="params">(oldItem, newItem)</span></span>;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure></p> <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"> <span class="comment">//AsyncPagedListDiffer.java 230行</span></span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">submitList</span><span class="params">(<span class="keyword">final</span> PagedList&lt;T&gt; pagedList)</span></span>&#123;</span><br><span class="line">              </span><br><span class="line">              <span class="comment">//······//</span></span><br><span class="line">           </span><br><span class="line">            mConfig.getBackgroundThreadExecutor().execute(<span class="keyword">new</span> Runnable() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                <span class="keyword">final</span> DiffUtil.DiffResult result;</span><br><span class="line">                <span class="comment">//调用PagedStorageHelper的computeDiff方法得到DiffResult</span></span><br><span class="line">                result = PagedStorageDiffHelper.computeDiff(</span><br><span class="line">                        oldSnapshot.mStorage,</span><br><span class="line">                        newSnapshot.mStorage,</span><br><span class="line">                        mConfig.getDiffCallback());</span><br><span class="line"></span><br><span class="line">                mMainThreadExecutor.execute(<span class="keyword">new</span> Runnable() &#123;</span><br><span class="line">                    <span class="meta">@Override</span></span><br><span class="line">                    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                        <span class="keyword">if</span> (mMaxScheduledGeneration == runGeneration) &#123;</span><br><span class="line">                  </span><br><span class="line">                          <span class="comment">//***********************调用了如下方法</span></span><br><span class="line">                            latchPagedList(pagedList, newSnapshot, result);</span><br><span class="line">                          <span class="comment">//************************</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line"></span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line"></span><br><span class="line">        <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">latchPagedList</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">            PagedList&lt;T&gt; newList, PagedList&lt;T&gt; diffSnapshot,</span></span></span><br><span class="line"><span class="function"><span class="params">            DiffUtil.DiffResult diffResult)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (mSnapshot == <span class="keyword">null</span> || mPagedList != <span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> IllegalStateException(<span class="string">"must be in snapshot state to apply diff"</span>);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        PagedList&lt;T&gt; previousSnapshot = mSnapshot;</span><br><span class="line">        mPagedList = newList;</span><br><span class="line">        mSnapshot = <span class="keyword">null</span>;</span><br><span class="line"><span class="comment">//mUpdateCallback = new AdapterListUpdateCallback(adapter);</span></span><br><span class="line">        </span><br><span class="line">        PagedStorageDiffHelper.dispatchDiff(mUpdateCallback,</span><br><span class="line">                previousSnapshot.mStorage, newList.mStorage, diffResult);<span class="comment">//result在这里出现了***************继续点击进去这个方法</span></span><br><span class="line"></span><br><span class="line">        newList.addWeakCallback(diffSnapshot, mPagedListCallback);</span><br><span class="line">        <span class="keyword">if</span> (mListener != <span class="keyword">null</span>) &#123;</span><br><span class="line">            mListener.onCurrentListChanged(mPagedList);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//PagedStorageDiffHelper result将数据发送给adapter</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> &lt;T&gt; <span class="function"><span class="keyword">void</span> <span class="title">dispatchDiff</span><span class="params">(ListUpdateCallback callback,</span></span></span><br><span class="line"><span class="function"><span class="params">            <span class="keyword">final</span> PagedStorage&lt;T&gt; oldList,</span></span></span><br><span class="line"><span class="function"><span class="params">            <span class="keyword">final</span> PagedStorage&lt;T&gt; newList,</span></span></span><br><span class="line"><span class="function"><span class="params">            <span class="keyword">final</span> DiffUtil.DiffResult diffResult)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">final</span> <span class="keyword">int</span> trailingOld = oldList.computeTrailingNulls();</span><br><span class="line">        <span class="keyword">final</span> <span class="keyword">int</span> trailingNew = newList.computeTrailingNulls();</span><br><span class="line">        <span class="keyword">final</span> <span class="keyword">int</span> leadingOld = oldList.computeLeadingNulls();</span><br><span class="line">        <span class="keyword">final</span> <span class="keyword">int</span> leadingNew = newList.computeLeadingNulls();</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (trailingOld == <span class="number">0</span></span><br><span class="line">                &amp;&amp; trailingNew == <span class="number">0</span></span><br><span class="line">                &amp;&amp; leadingOld == <span class="number">0</span></span><br><span class="line">                &amp;&amp; leadingNew == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="comment">// Simple case, dispatch &amp; return 发送数据给adapter</span></span><br><span class="line">            diffResult.dispatchUpdatesTo(callback);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">         <span class="comment">//········//</span></span><br><span class="line">        </span><br><span class="line">  </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>后续的直接看注释就可以了dispatchUpdatesTo方法传入的其实就是一个adapter，所以很显然，这些数据最终会发到adapter并且进行数据更新。再深入我也搞不来了，以后再说吧，先留个坑。</p><p><font color="red"><strong>其实到现在我们只是这么说，但是如何让数据更新时将新数据发送，实现submitList方法？这个我也没特别看懂。就比如下面这些，在adapter里的利用Java 8 Lambda方法的 <font color="orange">this :: submitList</font> 为什么能够返回Observer? 它是如何实现动态submitList的？</strong></font><br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 监听数据列表变化</span></span><br><span class="line">   <span class="keyword">private</span> <span class="keyword">final</span> Observer&lt;PagedList&lt;T&gt;&gt; mDataListObserver = <span class="keyword">this</span>::submitList;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">   <span class="comment">// 监听LoadMore状态</span></span><br><span class="line">   <span class="keyword">private</span> <span class="keyword">final</span> Observer&lt;NetworkStatus&gt; mLoadingObserver = networkStatus -&gt; &#123;</span><br><span class="line">       <span class="keyword">if</span> (networkStatus == <span class="keyword">null</span>) &#123;</span><br><span class="line">           <span class="keyword">return</span>;</span><br><span class="line">       &#125;</span><br><span class="line">       setLoadingStatus(networkStatus.getStatus());</span><br><span class="line">   &#125;;</span><br><span class="line"></span><br><span class="line">   <span class="comment">// 监听Refresh状态</span></span><br><span class="line">   <span class="keyword">private</span> <span class="keyword">final</span> Observer&lt;NetworkStatus&gt; mRefreshObserver = networkStatus -&gt; &#123;</span><br><span class="line">       <span class="keyword">if</span> (networkStatus == <span class="keyword">null</span>) &#123;</span><br><span class="line">           <span class="keyword">return</span>;</span><br><span class="line">       &#125;</span><br><span class="line">       setRefreshStatus(networkStatus.getStatus());</span><br><span class="line">   &#125;;</span><br><span class="line"></span><br><span class="line">   <span class="comment">// 监听是否为空列表</span></span><br><span class="line">   <span class="keyword">private</span> <span class="keyword">final</span> Observer&lt;Boolean&gt; mEmptyObserver = isEmpty -&gt; &#123;</span><br><span class="line">       <span class="keyword">if</span> (isEmpty == <span class="keyword">null</span>) &#123;</span><br><span class="line">           <span class="keyword">return</span>;</span><br><span class="line">       &#125;</span><br><span class="line">       setEmpty(isEmpty);</span><br><span class="line">   &#125;;</span><br><span class="line"></span><br><span class="line">   <span class="comment">// 监听是否有更多</span></span><br><span class="line">   <span class="keyword">private</span> <span class="keyword">final</span> Observer&lt;Boolean&gt; mHasMoreObserver = hasMore -&gt; &#123;</span><br><span class="line">       <span class="keyword">if</span> (hasMore == <span class="keyword">null</span>) &#123;</span><br><span class="line">           <span class="keyword">return</span>;</span><br><span class="line">       &#125;</span><br><span class="line">       setHasMore(hasMore);</span><br><span class="line">   &#125;;</span><br></pre></td></tr></table></figure></p><p>为什么要这么写呢？其实这个就是lambda语法里面比较狗的地方了<br>先看个例子吧<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//这是一段我从别的地方进行实验后搬来的代码，跟整体无关，</span></span><br><span class="line"><span class="comment">//这个说明了如果我们想对LiveData设置监听的话，必须传入一个LifeRecyclerOwner,一个Observer</span></span><br><span class="line"> feedViewModel.getArticleLiveData().observe(<span class="keyword">this</span>, <span class="keyword">new</span> Observer&lt;PagedList&lt;Article&gt;&gt;() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onChanged</span><span class="params">(@Nullable PagedList&lt;Article&gt; articles)</span> </span>&#123;</span><br><span class="line">                adapter.submitList(articles);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br></pre></td></tr></table></figure></p><p>所以学长的骚操作完全可以有三种方法实现  </p><ul><li><p><em>第一种 菜鸡乖乖写法</em></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line">   <span class="keyword">private</span> <span class="keyword">final</span> Observer&lt;PagedList&lt;T&gt;&gt; observer = <span class="keyword">new</span> Observer&lt;PagedList&lt;T&gt;&gt;() &#123;</span><br><span class="line">       <span class="meta">@Override</span></span><br><span class="line">       <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onChanged</span><span class="params">(@Nullable PagedList&lt;T&gt; ts)</span> </span>&#123;</span><br><span class="line">           getAdapter().submitList(ts);</span><br><span class="line">       &#125;</span><br><span class="line">   &#125;;</span><br></pre></td></tr></table></figure></li><li><p><em>第二种，小小进阶</em></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">final</span> Observer&lt;PagedList&lt;T&gt;&gt; observer = ts -&gt; <span class="keyword">this</span>.submitList(ts);</span><br></pre></td></tr></table></figure></li><li><p><em>第三种，灵魂代码手</em></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">final</span> Observer&lt;PagedList&lt;T&gt;&gt; mDataListObserver = <span class="keyword">this</span>::submitList;</span><br></pre></td></tr></table></figure></li></ul><h2 id="关于数据的绑定问题"><a href="#关于数据的绑定问题" class="headerlink" title="关于数据的绑定问题"></a>关于数据的绑定问题</h2><p>之前一直被我忽略掉了bindViewHolder方法<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onBindViewHolder</span><span class="params">(@NonNull RecyclerView.ViewHolder viewHolder, <span class="keyword">int</span> position)</span> </span>&#123;</span><br><span class="line">       <span class="keyword">int</span> type = getItemViewType(position);</span><br><span class="line">       <span class="comment">//前三种可能都是处理的异常情况</span></span><br><span class="line"></span><br><span class="line">       <span class="comment">//1.数据请求到底，没有数据可返回</span></span><br><span class="line">       <span class="keyword">if</span> (type == TYPE_EMPTY &amp;&amp; viewHolder <span class="keyword">instanceof</span> EmptyViewHolder) &#123;</span><br><span class="line">           ((EmptyViewHolder) viewHolder).bind((showLoadingStatusView() &amp;&amp; isAtEnd()), isEmpty());</span><br><span class="line"></span><br><span class="line">       <span class="comment">//2.正在加载数据</span></span><br><span class="line">       &#125; <span class="keyword">else</span> <span class="keyword">if</span> (type == TYPE_LOADING &amp;&amp; viewHolder <span class="keyword">instanceof</span> LoadingViewHolder) &#123;</span><br><span class="line">           ((LoadingViewHolder) viewHolder).bind();</span><br><span class="line"></span><br><span class="line">       <span class="comment">//3.数据出现错误</span></span><br><span class="line">       &#125; <span class="keyword">else</span> <span class="keyword">if</span> (type == TYPE_ERROR &amp;&amp; viewHolder <span class="keyword">instanceof</span> ErrorViewHolder) &#123;</span><br><span class="line">           ((ErrorViewHolder) viewHolder).bind(showLoadingStatusView());</span><br><span class="line">       <span class="comment">//4.正常情况，调用viewholder的bind方法，将data传入</span></span><br><span class="line">       &#125; <span class="keyword">else</span> <span class="keyword">if</span> (viewHolder <span class="keyword">instanceof</span> BaseViewHolder) &#123;</span><br><span class="line">           T data = getItem(position);</span><br><span class="line">           ((BaseViewHolder&lt;T&gt;) viewHolder).bind(data, position);</span><br><span class="line">       &#125;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure></p><p>如果这时候我们点进去getItem方法，发现这个是PagedListAdapter的方法，其中由使用了mDiffer.getItem()方法。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Nullable</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> T <span class="title">getItem</span><span class="params">(<span class="keyword">int</span> position)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> mDiffer.getItem(position);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure><p>这个mDiffer是个什么鬼？如果这时候你往上翻滚本文，在adapter实现过程的源码分析环节就可以看到这个mDiffer,这个是AsyncPagedListDiffer类的一个实例，我们之前知道了，当adapter调用了submit方法后，里面需要传入一个PagedList，然后这个pagedList就会赋值给AsyncPagedListDiffer里面的mPagedList,然后在getItem方法中可以通过mPagedList，根据位置调取单个实例。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Nullable</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> T <span class="title">getItem</span><span class="params">(<span class="keyword">int</span> index)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (mPagedList == <span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (mSnapshot == <span class="keyword">null</span>) &#123;</span><br><span class="line">                <span class="keyword">throw</span> <span class="keyword">new</span> IndexOutOfBoundsException(</span><br><span class="line">                        <span class="string">"Item count is zero, getItem() call is invalid"</span>);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="keyword">return</span> mSnapshot.get(index);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        mPagedList.loadAround(index);</span><br><span class="line">        <span class="keyword">return</span> mPagedList.get(index);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure><p>得到了单个item的data后，我们就可以将data和position传入viewholder类实例的bind方法，那么在自定义的viewholder继承BaseViewHolder，可以实现bind方法，将data与view绑定<br>以PriceItemViewHolder为例<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//重写了bind方法，参数为data,将数据与视图绑定</span></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">bind</span><span class="params">(Jade data, <span class="keyword">int</span> position)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        mGoodsTitleTxt.setText(data.getTitle());</span><br><span class="line">        mRangeTxt.setText(warpPercent(Math.abs(data.getRange())));</span><br><span class="line">        mSpeedTxt.setText(warpPercent(Math.abs(data.getSpeed())));</span><br><span class="line">        mRangeLabelTxt.setText(data.getRange() &gt;= <span class="number">0</span></span><br><span class="line">                ? R.string.price_label_range_rise</span><br><span class="line">                : R.string.price_label_range_drop);</span><br><span class="line">        mSpeedLabelTxt.setText(data.getSpeed() &gt;= <span class="number">0</span></span><br><span class="line">                ? R.string.price_label_speed_rise</span><br><span class="line">                : R.string.price_label_speed_drop);</span><br><span class="line">        Glide.with(itemView).load(data.getCover()).into(mCoverImg);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (withOrder) &#123;</span><br><span class="line">            mRankOrder.setText(String.valueOf(position + <span class="number">1</span>));</span><br><span class="line">            mRankOrder.setVisibility(View.VISIBLE);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            mRankOrder.setVisibility(View.GONE);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure></p><hr><h1 id="总结（UI部分还没看，先这么写一些）"><a href="#总结（UI部分还没看，先这么写一些）" class="headerlink" title="总结（UI部分还没看，先这么写一些）"></a>总结（UI部分还没看，先这么写一些）</h1><h2 id="Data-1"><a href="#Data-1" class="headerlink" title="Data"></a>Data</h2><ul><li>PagingDatasource用来请求数据，并且将数据返回给观察它的类。</li><li>PagingDtaSourceFactory是用来创建DataSource的实例的工具。<h2 id="ViewModel-1"><a href="#ViewModel-1" class="headerlink" title="ViewModel"></a>ViewModel</h2></li><li>PagingViewModel是能够创建各种LiveData的类，其中包括最重要的<code>LiveData&lt;PagedList&lt;T&gt;&gt;</code>,通过LivePagedListBuilder，传入PagingDataSourceFactory和Config（Config是配置类，规定了请求页数，初始请求数量等一些基本配置），最终得到需要的<code>LiveData&lt;PagedList&lt;T&gt;&gt;</code>.<h2 id="PaginListAdapter继承PagedListAdapter"><a href="#PaginListAdapter继承PagedListAdapter" class="headerlink" title="PaginListAdapter继承PagedListAdapter"></a>PaginListAdapter继承PagedListAdapter</h2><ul><li>构造方法：构造方法中需要传入DiffUtil.ItemCallback类。而且在adapter中可以实现submitList(LiveData&lt;PagedLsit<t>&gt;)方法，从而实现对数据变换的监视，数据变动时会发送给adapter.<strong><font color="yellow">(更新2019.8.2)： 今天更加深入理解之后，进行一个新的解释，在adapter里面实现了对LiveData的观察，当LiveData发生变动时，会调用submitList方法，将变动的数据传入，然后结合我上面的那些调用过程，在调用的过程大部分是在DiffUtil.itemCallback的包装类中，所以一定使用了DiffUtil.itemcallback类（在具体使用时实现）中的对比方法，从而只将变动的数据传回adapter，提高了效率。</font></strong></t></li><li>添加setViewModel方法：在活动中可以创建ViewModel实例，从而将实例传给adapter</li><li>提供抽象函数 CreateNormalViewHolder,用来创建不同页面的viewHolder.</li></ul></li></ul><h1 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h1><p>又可能上面这些东西你都看得觉得无比头疼，心想着我只需要知道怎么用就行了呀。行，那咱们就结合实例讲一讲怎么用  </p><ul><li>首先是ViewModel,由于增哥已经把PagingViewModel封装得很全面了，你只需要实现里面的抽象方法<br><code>protected abstract PagingDataSource&lt;T&gt; getDataSource();</code><br>例如我们进行一个请求<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">PersonalApi</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 获取我的预约评估列表</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> checkStatus 评估状态 : 送检中/已检验</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> checkRes    评估结果 : 通过/未通过</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> 预约列表</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@GET</span>(<span class="string">"check/records/me"</span>)</span><br><span class="line">    Call&lt;ApiResponse&lt;List&lt;JadeModel&gt;&gt;&gt; getMyEvaluationList(<span class="meta">@Query</span>(<span class="string">"check_status"</span>) String checkStatus,</span><br><span class="line">                                                          <span class="meta">@Query</span>(<span class="string">"check_res"</span>) String checkRes);</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ul><p>那么我们需要一个储藏室(repository)来进行数据请求以及实现接口回调</p>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;Paging学习&quot;&gt;&lt;a href=&quot;#Paging学习&quot; class=&quot;headerlink&quot; title=&quot;Paging学习&quot;&gt;&lt;/a&gt;Paging学习&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;Paging是Google 2018 IO大会最新发布的Jetpack中的一个组件，主要用于大数据的分页加载&lt;br&gt;&lt;/p&gt;&lt;/blockquote&gt;
    
    </summary>
    
      <category term="Android" scheme="http://yoursite.com/categories/Android/"/>
    
    
      <category term="Android" scheme="http://yoursite.com/tags/Android/"/>
    
      <category term="Java" scheme="http://yoursite.com/tags/Java/"/>
    
  </entry>
  
  <entry>
    <title>The port_set of your computer</title>
    <link href="http://yoursite.com/2019/07/06/The-port-set-of-your-computer/"/>
    <id>http://yoursite.com/2019/07/06/The-port-set-of-your-computer/</id>
    <published>2019-07-06T08:49:22.000Z</published>
    <updated>2019-08-27T11:55:12.758Z</updated>
    
    <content type="html"><![CDATA[<a id="more"></a><p>If you want to connect to a remote port, you should use the command of  </p><blockquote><p>‘netset localhost </p></blockquote><p>release the occupation of port<br>–&gt;<a href="https://blog.csdn.net/IUNIQUE/article/details/79750983" target="_blank" rel="noopener">解除端口占用</a></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;p&gt;If you want to connect to a remote port, you should use the command of  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;‘netset localhost &lt;/p&gt;
&lt;/b
      
    
    </summary>
    
      <category term="Java" scheme="http://yoursite.com/categories/Java/"/>
    
    
      <category term="Java" scheme="http://yoursite.com/tags/Java/"/>
    
      <category term="cmd" scheme="http://yoursite.com/tags/cmd/"/>
    
  </entry>
  
  <entry>
    <title>离散数学—_函数</title>
    <link href="http://yoursite.com/2019/06/21/%E7%A6%BB%E6%95%A3%E6%95%B0%E5%AD%A6%E2%80%94-%E5%87%BD%E6%95%B0/"/>
    <id>http://yoursite.com/2019/06/21/离散数学—-函数/</id>
    <published>2019-06-21T12:35:21.000Z</published>
    <updated>2019-08-27T12:05:25.530Z</updated>
    
    <content type="html"><![CDATA[<p>It’s a test centence<br><a id="more"></a>  </p><p><img src="/2019/06/21/离散数学—-函数/函数.png" alt></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;It’s a test centence&lt;br&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="离散数学" scheme="http://yoursite.com/categories/%E7%A6%BB%E6%95%A3%E6%95%B0%E5%AD%A6/"/>
    
    
      <category term="离散数学" scheme="http://yoursite.com/tags/%E7%A6%BB%E6%95%A3%E6%95%B0%E5%AD%A6/"/>
    
  </entry>
  
  <entry>
    <title>离散数学-二元关系</title>
    <link href="http://yoursite.com/2019/06/20/%E7%A6%BB%E6%95%A3%E6%95%B0%E5%AD%A6-%E4%BA%8C%E5%85%83%E5%85%B3%E7%B3%BB/"/>
    <id>http://yoursite.com/2019/06/20/离散数学-二元关系/</id>
    <published>2019-06-20T13:55:22.000Z</published>
    <updated>2019-08-27T12:06:28.423Z</updated>
    
    <content type="html"><![CDATA[<h1 id="离散数学二元关系思维导图"><a href="#离散数学二元关系思维导图" class="headerlink" title="离散数学二元关系思维导图"></a>离散数学二元关系思维导图</h1><a id="more"></a><p><img src="/2019/06/20/离散数学-二元关系/二元关系.png" alt></p>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;离散数学二元关系思维导图&quot;&gt;&lt;a href=&quot;#离散数学二元关系思维导图&quot; class=&quot;headerlink&quot; title=&quot;离散数学二元关系思维导图&quot;&gt;&lt;/a&gt;离散数学二元关系思维导图&lt;/h1&gt;
    
    </summary>
    
      <category term="离散数学" scheme="http://yoursite.com/categories/%E7%A6%BB%E6%95%A3%E6%95%B0%E5%AD%A6/"/>
    
    
      <category term="离散数学" scheme="http://yoursite.com/tags/%E7%A6%BB%E6%95%A3%E6%95%B0%E5%AD%A6/"/>
    
  </entry>
  
  <entry>
    <title>RecyclerViewBaseAdapter基础封装</title>
    <link href="http://yoursite.com/2019/06/19/RecyclerViewBaseAdapter%E5%9F%BA%E7%A1%80%E5%B0%81%E8%A3%85/"/>
    <id>http://yoursite.com/2019/06/19/RecyclerViewBaseAdapter基础封装/</id>
    <published>2019-06-19T10:03:25.000Z</published>
    <updated>2019-06-19T11:56:43.596Z</updated>
    
    <content type="html"><![CDATA[<h1 id="RecycelrViewAdapter的封装"><a href="#RecycelrViewAdapter的封装" class="headerlink" title="RecycelrViewAdapter的封装"></a>RecycelrViewAdapter的封装</h1><p>It’s well known that RecyclerView is a powerful tool to create a list view or a grid view, however, it’s also complicated to use.<br><a id="more"></a><br>There’s a passage I writed a few months ago, in this passage I used an example to show the basic usage of RecyclerView.<br>—&gt;<a href="https://github.com/han1254/Study/blob/master/Android/RecyclerView/%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95.md" target="_blank" rel="noopener">RecyclerView基础用法</a></p><p>So in my opinion, there are six steps to use RecyclerView.</p><ul><li>Add dependecy of RecyclerView</li><li>Create an activity/fragment, and use the control in it’s layout file.</li><li>Create an item, which is the model of your every list’s view.</li><li>Create a class as a model, which contains the information that is needed in every item.</li><li>Create an adapter.</li><li>Use it in your activity or fragment.</li></ul><p>The most important step is step 5, an adapter is so complicated to create. So how can we solve the problem?</p><p>There is a princple in Java: <strong>High cohesion, low coupling</strong>,so we would better to separate the viewHolder from RecyclerViewAdapter<br>So first, we can create a base adapter.</p><h2 id="BaseRecyclerViewAdapter"><a href="#BaseRecyclerViewAdapter" class="headerlink" title="BaseRecyclerViewAdapter"></a>BaseRecyclerViewAdapter</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">BaseRecyclerViewAdapter</span>&lt;<span class="title">Data</span>&gt; <span class="keyword">extends</span> <span class="title">RecyclerView</span>.<span class="title">Adapter</span>&lt;<span class="title">BaseViewHolder</span>&gt; </span>&#123;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">protected</span> List&lt;Data&gt; mDataList;</span><br><span class="line">    <span class="keyword">protected</span> Context mContext;</span><br><span class="line">    <span class="keyword">protected</span> LayoutInflater mInflater;</span><br><span class="line">    <span class="keyword">protected</span> <span class="keyword">int</span> mItemLayoutId;</span><br><span class="line">    <span class="keyword">private</span> OnItemClickListener mOnItemClickListener;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">BaseRecyclerViewAdapter</span><span class="params">(List&lt;Data&gt; dataList, Context context, @LayoutRes <span class="keyword">int</span> itemLayoutId)</span> </span>&#123;</span><br><span class="line">        mDataList = dataList;</span><br><span class="line">        mContext = context;</span><br><span class="line">        mInflater = LayoutInflater.from(mContext);</span><br><span class="line">        mItemLayoutId = itemLayoutId;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onBindViewHolder</span><span class="params">(BaseViewHolder holder, <span class="keyword">final</span> <span class="keyword">int</span> position)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        holder.itemView.setOnClickListener(<span class="keyword">new</span> View.OnClickListener() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">                <span class="keyword">if</span> (mOnItemClickListener != <span class="keyword">null</span>) &#123;</span><br><span class="line">                    mOnItemClickListener.onItemClick(v, mDataList.get(position), position);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">        bindView(holder, mDataList.get(position));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 绑定item中的view和数据</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> viewHolder</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> item</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">bindView</span><span class="params">(BaseViewHolder viewHolder, Data item)</span></span>;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="meta">@SuppressWarnings</span>(<span class="string">"unchecked"</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> BaseViewHolder <span class="title">onCreateViewHolder</span><span class="params">(ViewGroup parent, <span class="keyword">int</span> viewType)</span> </span>&#123;</span><br><span class="line">        View view = mInflater.inflate(mItemLayoutId, parent, <span class="keyword">false</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> BaseViewHolder(mContext, view);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getItemCount</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> mDataList.size();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 设置数据</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> data 数据</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setDataList</span><span class="params">(Collection&lt;Data&gt; data)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.mDataList.clear();</span><br><span class="line">        <span class="keyword">this</span>.mDataList.addAll(data);</span><br><span class="line">        notifyDataSetChanged();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 获取当前列表的数据</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> List&lt;Data&gt; <span class="title">getDataList</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>.mDataList;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 添加数据</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> data</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addItem</span><span class="params">(Data data)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.mDataList.add(data);</span><br><span class="line">        notifyDataSetChanged();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> collection</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addItems</span><span class="params">(Collection&lt;Data&gt; collection)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.mDataList.addAll(collection);</span><br><span class="line">        notifyDataSetChanged();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 移除数据</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> data 移除的数据</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">removeItem</span><span class="params">(Data data)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.mDataList.remove(data);</span><br><span class="line">        notifyDataSetChanged();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 移除数据（带动画）</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> position pos</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">removeItem</span><span class="params">(<span class="keyword">int</span> position)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.mDataList.remove(position);</span><br><span class="line">        <span class="comment">//该方法不会使position及其之后位置的itemView重新onBindViewHolder</span></span><br><span class="line">        notifyItemRemoved(position);</span><br><span class="line">        <span class="comment">//所以需要从position到列表末尾进行数据刷新</span></span><br><span class="line">        notifyItemRangeChanged(position, mDataList.size() - position);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 清除全部数据</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">removeAllItem</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        mDataList.clear();</span><br><span class="line">        notifyDataSetChanged();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 获取position 处数据</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Data <span class="title">getItem</span><span class="params">(<span class="keyword">int</span> position)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> mDataList.get(position);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 刷新页面</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">refresh</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        notifyDataSetChanged();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">refresh</span><span class="params">(<span class="keyword">int</span> position)</span> </span>&#123;</span><br><span class="line">        notifyItemChanged(position);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">OnItemClickListener</span>&lt;<span class="title">Data</span>&gt; </span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 点击事件回调</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         * <span class="doctag">@param</span> view</span></span><br><span class="line"><span class="comment">         * <span class="doctag">@param</span> position</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onItemClick</span><span class="params">(View view, Data data, <span class="keyword">int</span> position)</span></span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setOnItemClickListener</span><span class="params">(OnItemClickListener onItemClickListener)</span> </span>&#123;</span><br><span class="line">        mOnItemClickListener = onItemClickListener;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>So We just look at the basic ones.<br>It’s obviou that in the class we override the three classic methods–<strong>onCreateViewHolder(),onBindViewHolder(),getItemCount()</strong>;<br>First, we create a ViewHolder<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line">    <span class="meta">@SuppressWarnings</span>(<span class="string">"unchecked"</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> BaseViewHolder <span class="title">onCreateViewHolder</span><span class="params">(ViewGroup parent, <span class="keyword">int</span> viewType)</span> </span>&#123;</span><br><span class="line">        View view = mInflater.inflate(mItemLayoutId, parent, <span class="keyword">false</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> BaseViewHolder(mContext, view);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure></p><p>Then we will bind the holder to the data<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onBindViewHolder</span><span class="params">(BaseViewHolder holder, <span class="keyword">final</span> <span class="keyword">int</span> position)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        holder.itemView.setOnClickListener(<span class="keyword">new</span> View.OnClickListener() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">                <span class="keyword">if</span> (mOnItemClickListener != <span class="keyword">null</span>) &#123;</span><br><span class="line">                    mOnItemClickListener.onItemClick(v, mDataList.get(position), position);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">        bindView(holder, mDataList.get(position));</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure></p><p><em>we also set clicklistener to the item</em><br>We don’t directly bind the data to the view because we don’t exactly know how many data,how many controls need to be binded, so we should define an abstract method to be override in different situation. That’s why we use the <strong>bindView()</strong>.  </p><p>So we just need to override two methods–<strong>the constuction methond of your class</strong> and <strong>the bindView()</strong> if we want to use it in subclass.</p><p>The getItemCount() is so easy that we don’t talk about it.</p><hr><h2 id="BaseViewHolder"><a href="#BaseViewHolder" class="headerlink" title="BaseViewHolder"></a>BaseViewHolder</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">BaseViewHolder</span> <span class="keyword">extends</span> <span class="title">RecyclerView</span>.<span class="title">ViewHolder</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> SparseArray&lt;View&gt; mViewSparseArray;</span><br><span class="line">    <span class="keyword">private</span> Context mContext;</span><br><span class="line">    <span class="keyword">private</span> View mItemView;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">BaseViewHolder</span><span class="params">(Context context, View itemView)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(itemView);</span><br><span class="line">        <span class="keyword">this</span>.mContext = context;</span><br><span class="line">        mItemView = itemView;</span><br><span class="line">        mViewSparseArray = <span class="keyword">new</span> SparseArray&lt;&gt;();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 从布局获取泛型view</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> viewId</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> &lt;T&gt;</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@SuppressWarnings</span>(<span class="string">"unchecked"</span>)</span><br><span class="line">    <span class="keyword">protected</span> &lt;T extends View&gt; <span class="function">T <span class="title">findViewById</span><span class="params">(@IdRes <span class="keyword">int</span> viewId)</span> </span>&#123;</span><br><span class="line">        <span class="comment">//从已经缓存的ViewMap中查找</span></span><br><span class="line">        View view = mViewSparseArray.get(viewId);</span><br><span class="line">        <span class="comment">//如果没有缓存</span></span><br><span class="line">        <span class="keyword">if</span> (view == <span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="comment">//获取实例并加入缓存</span></span><br><span class="line">            view = mItemView.findViewById(viewId);</span><br><span class="line">            mViewSparseArray.append(viewId, view);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> (T) view;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 设置TextView类型</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> viewId</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> value</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> BaseViewHolder <span class="title">setText</span><span class="params">(@IdRes <span class="keyword">int</span> viewId, @StringRes <span class="keyword">int</span> value)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> setText(viewId, mContext.getString(value));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> BaseViewHolder <span class="title">setText</span><span class="params">(@IdRes <span class="keyword">int</span> viewId, String value)</span> </span>&#123;</span><br><span class="line">        TextView textView = findViewById(viewId);</span><br><span class="line">        textView.setText(value == <span class="keyword">null</span> ? mContext.getString(R.string.empty) : value);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 设置ImageView的url</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> viewId</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> value</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> BaseViewHolder <span class="title">setImgUrl</span><span class="params">(@IdRes <span class="keyword">int</span> viewId, String value)</span> </span>&#123;</span><br><span class="line">        ImageView imageView = findViewById(viewId);</span><br><span class="line">        <span class="keyword">if</span> (value != <span class="keyword">null</span>) &#123;</span><br><span class="line">            Glide.with(mContext)</span><br><span class="line">                    .load(value)</span><br><span class="line">                    .transition(GenericTransitionOptions.&lt;Drawable&gt;withNoTransition())</span><br><span class="line">                    .into(imageView);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 设置ImageView的url</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> viewId</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> BaseViewHolder <span class="title">setImgRes</span><span class="params">(@IdRes <span class="keyword">int</span> viewId, @DrawableRes <span class="keyword">int</span> drawableId)</span> </span>&#123;</span><br><span class="line">        ImageView imageView = findViewById(viewId);</span><br><span class="line">        imageView.setImageResource(drawableId);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 设置控件是否可见</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> viewId</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> isVisible</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> BaseViewHolder <span class="title">setVisible</span><span class="params">(@IdRes <span class="keyword">int</span> viewId, <span class="keyword">boolean</span> isVisible)</span> </span>&#123;</span><br><span class="line">        findViewById(viewId).setVisibility(isVisible ? View.VISIBLE : View.INVISIBLE);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 设置控件是否消失(不保留空间)</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> BaseViewHolder <span class="title">setGone</span><span class="params">(@IdRes <span class="keyword">int</span> viewId)</span> </span>&#123;</span><br><span class="line">        findViewById(viewId).setVisibility(View.GONE);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 获取item的View</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> View <span class="title">getItemView</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> mItemView;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 获取item内部的view</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> viewId</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> View <span class="title">getViewById</span><span class="params">(@IdRes <span class="keyword">int</span> viewId)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> findViewById(viewId);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 获取当前viewHolder位置</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getViewHolderPosition</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> getAdapterPosition();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>The annotate is so clear, from the code of BaseRecyclerViewAdatper we can know that if we want to use the methond bindView(), we should put the parameters of viewHolder which is the type of BaseViewHolder, so in the method, we can use the methods of viewHolder such as <strong>setTxt(), setImageRes()</strong> to bind the controls the view.<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">    * 绑定item中的view和数据</span></span><br><span class="line"><span class="comment">    *</span></span><br><span class="line"><span class="comment">    * <span class="doctag">@param</span> viewHolder</span></span><br><span class="line"><span class="comment">    * <span class="doctag">@param</span> item</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">   <span class="function"><span class="keyword">protected</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">bindView</span><span class="params">(BaseViewHolder viewHolder, Data item)</span></span>;</span><br></pre></td></tr></table></figure></p><p>So how easy the way to use RecyclerViewAdapter can be if we use the BaseRecyclerViewAdapter? Don’t worry, there is an example<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CantDoListAdapter</span> <span class="keyword">extends</span> <span class="title">BaseRecyclerViewAdapter</span>&lt;<span class="title">CalendarModel</span>.<span class="title">BadBean</span>&gt; </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">CantDoListAdapter</span><span class="params">(List&lt;CalendarModel.BadBean&gt; badBeanList, Context context, <span class="keyword">int</span> itemLayoutId)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(badBeanList, context, itemLayoutId);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">bindView</span><span class="params">(BaseViewHolder viewHolder, CalendarModel.BadBean item)</span> </span>&#123;</span><br><span class="line">        viewHolder.setText(R.id.item_calendar_can_do,item.getTitle())</span><br><span class="line">                .setText(R.id.item_calendar_can_do_detail,item.getDescription());</span><br><span class="line">        ImageView imageView = (ImageView)viewHolder.getItemView().findViewById(R.id.item_image_flag);</span><br><span class="line">        imageView.setBackgroundColor(mContext.getResources().getColor(R.color.red));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><p>Is so easy, isn’t it?</p>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;RecycelrViewAdapter的封装&quot;&gt;&lt;a href=&quot;#RecycelrViewAdapter的封装&quot; class=&quot;headerlink&quot; title=&quot;RecycelrViewAdapter的封装&quot;&gt;&lt;/a&gt;RecycelrViewAdapter的封装&lt;/h1&gt;&lt;p&gt;It’s well known that RecyclerView is a powerful tool to create a list view or a grid view, however, it’s also complicated to use.&lt;br&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Android" scheme="http://yoursite.com/categories/Android/"/>
    
    
      <category term="android" scheme="http://yoursite.com/tags/android/"/>
    
      <category term="封装" scheme="http://yoursite.com/tags/%E5%B0%81%E8%A3%85/"/>
    
  </entry>
  
  <entry>
    <title>Java异常</title>
    <link href="http://yoursite.com/2019/06/16/Java%E5%BC%82%E5%B8%B8/"/>
    <id>http://yoursite.com/2019/06/16/Java异常/</id>
    <published>2019-06-16T11:01:54.000Z</published>
    <updated>2019-06-16T12:14:16.190Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Java异常"><a href="#Java异常" class="headerlink" title="Java异常"></a>Java异常</h1><a id="more"></a><ol><li><strong>throws &amp; throw</strong><br>如果方法声明后有throw语句，则在此方法被调用时，需要<strong>在调用方法中用try和catch进行异常捕获</strong>，如果不捕获异常，则需要在调用方法中使用throws语句将异常抛出。</li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.util.*;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">A</span><span class="params">(<span class="keyword">int</span> a)</span><span class="keyword">throws</span> Exception,IllegalArgumentException</span>&#123;</span><br><span class="line"><span class="keyword">if</span>(a == <span class="number">0</span>) &#123;</span><br><span class="line"><span class="keyword">throw</span> <span class="keyword">new</span> Exception(<span class="string">"a=0,silly boy!"</span>);</span><br><span class="line">&#125;<span class="keyword">else</span> <span class="keyword">if</span>(a == <span class="number">1</span>) &#123;</span><br><span class="line">IllegalArgumentException str=<span class="keyword">new</span> IllegalArgumentException(<span class="string">"a=1, IllegalArgumentException"</span>);</span><br><span class="line"><span class="keyword">throw</span> str;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> a;</span><br><span class="line">Scanner t = <span class="keyword">new</span> Scanner(System.in);</span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line">a = t.nextInt();</span><br><span class="line">A(a);</span><br><span class="line">&#125;<span class="keyword">catch</span>(IllegalArgumentException e2) &#123;</span><br><span class="line">System.out.println(e2.toString());</span><br><span class="line">&#125;<span class="keyword">catch</span>(Exception e)&#123;</span><br><span class="line">System.out.println(e.toString());</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>例如我们在上面的代码里定义了一个A方法，在这个方法里我们用<strong>throws</strong>声明了可能抛出的异常，然后我们需要在方法体里把异常实例化并且利用<strong>throw</strong>将其抛出。</p><p>在主方法中，我们利用<strong>try-catch</strong>语句，将可能出现异常的语句用try包括起来，然后利用catch语句来承接这个异常，并且输出异常。</p><p>那么接下来就是另外一个问题</p><ol start="2"><li><strong>toString, getMessage, printStackTrace</strong><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.util.*;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">A</span><span class="params">(<span class="keyword">int</span> a)</span><span class="keyword">throws</span> Exception,IllegalArgumentException</span>&#123;</span><br><span class="line"><span class="keyword">if</span>(a == <span class="number">0</span>) &#123;</span><br><span class="line"><span class="keyword">throw</span> <span class="keyword">new</span> Exception(<span class="string">"a=0,silly boy!"</span>);</span><br><span class="line">&#125;<span class="keyword">else</span> <span class="keyword">if</span>(a == <span class="number">1</span>) &#123;</span><br><span class="line">IllegalArgumentException str=<span class="keyword">new</span> IllegalArgumentException(<span class="string">"a=1, bitch"</span>);</span><br><span class="line"><span class="keyword">throw</span> str;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> a;</span><br><span class="line">Scanner t = <span class="keyword">new</span> Scanner(System.in);</span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line">a = t.nextInt();</span><br><span class="line">A(a);</span><br><span class="line">&#125;<span class="keyword">catch</span>(IllegalArgumentException e2) &#123;</span><br><span class="line">System.out.println(e2.toString());</span><br><span class="line">System.out.println();</span><br><span class="line">System.out.println(e2.getMessage());</span><br><span class="line">System.out.println();</span><br><span class="line">e2.printStackTrace();</span><br><span class="line">&#125;<span class="keyword">catch</span>(Exception e)&#123;</span><br><span class="line">System.out.println(e.toString());</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ol><p>输入1，结果：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">java.lang.IllegalArgumentException: a=<span class="number">1</span>, bitch</span><br><span class="line"></span><br><span class="line">a=<span class="number">1</span>, bitch</span><br><span class="line"></span><br><span class="line">java.lang.IllegalArgumentException: a=<span class="number">1</span>, bitch</span><br><span class="line">at 异常.Main.A(Main.java:<span class="number">10</span>)</span><br><span class="line">at 异常.Main.main(Main.java:<span class="number">20</span>)</span><br><span class="line"></span><br><span class="line">`</span><br></pre></td></tr></table></figure></p><ol start="3"><li><strong>最后还有一点，子类父类的问题</strong><br>子类异常要放在前面，父类异常要写在后面  </li></ol><p><img src="http://dl2.iteye.com/upload/attachment/0120/1194/9c234fae-d8be-3479-8275-ffceee4c7b84.jpg" alt></p>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;Java异常&quot;&gt;&lt;a href=&quot;#Java异常&quot; class=&quot;headerlink&quot; title=&quot;Java异常&quot;&gt;&lt;/a&gt;Java异常&lt;/h1&gt;
    
    </summary>
    
      <category term="Java" scheme="http://yoursite.com/categories/Java/"/>
    
    
      <category term="Java" scheme="http://yoursite.com/tags/Java/"/>
    
  </entry>
  
  <entry>
    <title>OJ_Tower of Hanoi</title>
    <link href="http://yoursite.com/2019/06/15/OJ-Tower-of-Hanoi/"/>
    <id>http://yoursite.com/2019/06/15/OJ-Tower-of-Hanoi/</id>
    <published>2019-06-15T15:20:23.000Z</published>
    <updated>2019-06-15T17:08:23.008Z</updated>
    
    <content type="html"><![CDATA[<p>I still remember the day when I was sitting in the classroom of Mr.Wang(<em>Wang Hexing is a handsome teacher</em>)listening him to talking about the question–<strong>Tower of Hanoi</strong>, and I still remember the confusion in my little head.<br><a id="more"></a><br><img src="/2019/06/15/OJ-Tower-of-Hanoi/title.jpg" alt><br>Just as the saying goes: <em>The man who comes out to play is always have to pay back</em>.  I finally met it on NEUQ_oj.  </p><p>I think it’s time for me to know what the Tower of Hanoi is and find out how to solve it.</p><h3 id="The-question"><a href="#The-question" class="headerlink" title="The question:"></a>The question:</h3><blockquote><p>The problem of the Tower of Hanoi (also known as the Hanoi Tower) is an educational toy derived from an ancient legend of India. When Brahma created the world, he made three diamond pillars, and on a pillar, he smashed 64 gold discs in order of size from bottom to top. Brahma ordered the Brahmin to reposition the discs on the other column in order of size from below. It is also stipulated that the disc cannot be enlarged on the small disc, and only one disc can be moved at a time between the three columns.</p></blockquote><h1 id="Analysis"><a href="#Analysis" class="headerlink" title="Analysis"></a>Analysis</h1><p>It’s obviously that we should use the <strong>recursive function</strong>, but the question is ‘How’?</p><p>First, let’s find some laws in the question.Look at the pictures:</p><ul><li><strong>The number of discs is one</strong><br><img src="/2019/06/15/OJ-Tower-of-Hanoi/1.png" alt><br><img src="/2019/06/15/OJ-Tower-of-Hanoi/2.png" alt></li></ul><hr><ul><li><strong>The number of discs is two</strong></li></ul><p><img src="/2019/06/15/OJ-Tower-of-Hanoi/14.png" alt><br><img src="/2019/06/15/OJ-Tower-of-Hanoi/3.png" alt><br><img src="/2019/06/15/OJ-Tower-of-Hanoi/4.png" alt><br><img src="/2019/06/15/OJ-Tower-of-Hanoi/5.png" alt></p><p><em>In this part, we use the pillar B as a transformer station, what? transformer station? Don’t worry, We will explain the usage of it.</em></p><hr><ul><li><strong>The number of discs is three</strong></li></ul><p><img src="/2019/06/15/OJ-Tower-of-Hanoi/6.png" alt></p><p><strong>First we should know our target. We want to move the all pillars to pillar C. It’s obvious that it is impossible to make it at once. So we should find a transformer station. We can move the green one and blue one to pillar B.</strong></p><p><img src="/2019/06/15/OJ-Tower-of-Hanoi/7.png" alt><br><img src="/2019/06/15/OJ-Tower-of-Hanoi/8.png" alt><br><img src="/2019/06/15/OJ-Tower-of-Hanoi/9.png" alt><br><img src="/2019/06/15/OJ-Tower-of-Hanoi/10.png" alt></p><p><strong>So we can use the way in the situation of two discs to move green and blue to B, and then move the red one to C</strong></p><p><img src="/2019/06/15/OJ-Tower-of-Hanoi/11.png" alt><br><img src="/2019/06/15/OJ-Tower-of-Hanoi/12.png" alt><br><img src="/2019/06/15/OJ-Tower-of-Hanoi/13.png" alt></p><p><strong>The last thing we should do is to use the same way of situation of two discs and think pillar A as a transfer station</strong></p><hr><h1 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h1><p>We have analyze the basic idea of Hanoi, so it is time for us to explore the way to achieve it in code.</p><p>As I have said on the begin of the passage, we should use the recursive fuction, because it’s the simplest way to solve the question.</p><p>the parameter is four:</p><ul><li>the number of discs</li><li>the pillar that the discs you want to move exist.</li><li>the transfer station</li><li>the target pillar at every step</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">void hanoi(int n, char A, char B, char C)&#123;</span><br><span class="line">    if(n == 1)&#123;</span><br><span class="line">        printf(&quot;Move sheet %d from %c to %c\n&quot;,n,A,C);</span><br><span class="line">    &#125;else&#123;</span><br><span class="line">        //as we can see, if we want get the result of n,</span><br><span class="line">//we should move n - 1 first, so here we need to</span><br><span class="line">//use the way of recursion</span><br><span class="line"></span><br><span class="line">//here we need to move the n - 1 smaller discs from </span><br><span class="line">//A to B</span><br><span class="line">hanoi(n-1, A,C,B);</span><br><span class="line"></span><br><span class="line">//here we move the left biggest one from A to C</span><br><span class="line">printf(&quot;Move sheet %d from %c to %c\n&quot;,n,A,C);</span><br><span class="line"></span><br><span class="line">//here we move the n - 1 samller discs from B to C</span><br><span class="line">hanoi(n-1, B, A, C);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="Conclusion"><a href="#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h1><p>If there is any error, please contract with me and teach me how to correct it or I can try my best to correct it myself. I am just a vegetable chicken.</p><p>Please bear with me.<br>o((⊙﹏⊙))o.<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">/*</span><br><span class="line">*      </span><br><span class="line">*          ┌─┐       ┌─┐</span><br><span class="line">*       ┌──┘ ┴───────┘ ┴──┐</span><br><span class="line">*       │                 │</span><br><span class="line">*       │       ───       │</span><br><span class="line">*       │  ─┬┘       └┬─  │</span><br><span class="line">*       │                 │</span><br><span class="line">*       │       ─┴─       │</span><br><span class="line">*       │                 │</span><br><span class="line">*       └───┐         ┌───┘</span><br><span class="line">*           │         │</span><br><span class="line">*           │         │</span><br><span class="line">*           │         │</span><br><span class="line">*           │         └──────────────┐</span><br><span class="line">*           │                        │</span><br><span class="line">*           │                        ├─┐</span><br><span class="line">*           │                        ┌─┘    </span><br><span class="line">*           │                        │</span><br><span class="line">*           └─┐  ┐  ┌───────┬──┐  ┌──┘         </span><br><span class="line">*             │ ─┤ ─┤       │ ─┤ ─┤         </span><br><span class="line">*             └──┴──┘       └──┴──┘ </span><br><span class="line">*                 神兽保佑 </span><br><span class="line">*                 代码无BUG! </span><br><span class="line">*/</span><br></pre></td></tr></table></figure></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;I still remember the day when I was sitting in the classroom of Mr.Wang(&lt;em&gt;Wang Hexing is a handsome teacher&lt;/em&gt;)listening him to talking about the question–&lt;strong&gt;Tower of Hanoi&lt;/strong&gt;, and I still remember the confusion in my little head.&lt;br&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="algrithom" scheme="http://yoursite.com/categories/algrithom/"/>
    
      <category term="Tower of Hanoi" scheme="http://yoursite.com/categories/algrithom/Tower-of-Hanoi/"/>
    
    
      <category term="OJ" scheme="http://yoursite.com/tags/OJ/"/>
    
      <category term="algrithom" scheme="http://yoursite.com/tags/algrithom/"/>
    
  </entry>
  
  <entry>
    <title>Java_deepToString方法</title>
    <link href="http://yoursite.com/2019/06/14/Java-deepToString%E6%96%B9%E6%B3%95/"/>
    <id>http://yoursite.com/2019/06/14/Java-deepToString方法/</id>
    <published>2019-06-14T07:15:18.000Z</published>
    <updated>2019-06-14T07:15:18.618Z</updated>
    
    <summary type="html">
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>NEUQOJ-1016-Roliygu&amp;Yilan</title>
    <link href="http://yoursite.com/2019/06/12/NEUQOJ-1016-Roliygu-Yilan/"/>
    <id>http://yoursite.com/2019/06/12/NEUQOJ-1016-Roliygu-Yilan/</id>
    <published>2019-06-12T07:27:19.000Z</published>
    <updated>2019-06-12T08:01:34.068Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>Roliygu is famous because he likes to play games. Today he puts a chessboard in the desktop,and plays a game with Yilan. The size of the chessboard is n by n. A stone is placed in a corner square. They play alternatively with Roliygu having the first move. Each time,player is allowed to move the stone to an unvisited neighbor square horizontally or vertically. The one who can’t make a move will lose the game. If both play perfectly, who will win the game?</p></blockquote><a id="more"></a><h2 id="Input"><a href="#Input" class="headerlink" title="Input"></a>Input</h2><blockquote><p>The input is a sequence of positive integers each in a separate line. The integers are between 1 and 10 000,inclusive,indicating the size of the chessboard. The end of the input is indicated by a zero.  </p></blockquote><h2 id="Output"><a href="#Output" class="headerlink" title="Output"></a>Output</h2><blockquote><p>Output the winner(“Roliygu” or “Yilan”) for each input line except the last zero. No other characters should be inserted in the output.</p></blockquote><h1 id="Analysis"><a href="#Analysis" class="headerlink" title="Analysis"></a>Analysis</h1><p>This question is hard if we try to solve it just as the description of the question, however, we can change our mind to think about the question, can we get the result of who will win if we just know the <strong>odevity</strong> of the grid of the board and the <strong>upper-hand player</strong>? The anwser is YES!</p><p>Let’s look at the two pictures below:</p><p><img src="/2019/06/12/NEUQOJ-1016-Roliygu-Yilan/1.jpg" alt></p><p><img src="/2019/06/12/NEUQOJ-1016-Roliygu-Yilan/2.jpg" alt></p><p>if the grids’ number is even, if obvious that all of the grids and be divided into some pices of 1*2, what is very important for you to know is that the start point is in one grid, so the left grids’ number is actually odd, so you can know that <strong>who first, who win</strong>;</p><p>In the same way we can know that if the grids’ number is odd, the number except the start point will be even, so <strong>who later, who win</strong>;</p><p>So the question has been changed into <strong>Jugement of the odevity of the board’s grids number</strong>, it’s easy, isn’t it?</p><h1 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">#include &lt;iostream&gt;</span><br><span class="line">using namespace std;</span><br><span class="line">int main()</span><br><span class="line">&#123;</span><br><span class="line">    int n;</span><br><span class="line">    while(cin&gt;&gt;n)</span><br><span class="line">    &#123;</span><br><span class="line">        if(n == 0)</span><br><span class="line">        &#123;</span><br><span class="line">            break;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        if(n * n % 2 == 0)</span><br><span class="line">        &#123;</span><br><span class="line">            cout&lt;&lt;&quot;Roliygu&quot;&lt;&lt;endl;</span><br><span class="line">        &#125;</span><br><span class="line">        else</span><br><span class="line">        &#123;</span><br><span class="line">            cout&lt;&lt;&quot;Yilan&quot;&lt;&lt;endl;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Roliygu is famous because he likes to play games. Today he puts a chessboard in the desktop,and plays a game with Yilan. The size of the chessboard is n by n. A stone is placed in a corner square. They play alternatively with Roliygu having the first move. Each time,player is allowed to move the stone to an unvisited neighbor square horizontally or vertically. The one who can’t make a move will lose the game. If both play perfectly, who will win the game?&lt;/p&gt;
&lt;/blockquote&gt;
    
    </summary>
    
      <category term="NEUQOJ" scheme="http://yoursite.com/categories/NEUQOJ/"/>
    
      <category term="1016" scheme="http://yoursite.com/categories/NEUQOJ/1016/"/>
    
    
      <category term="OJ" scheme="http://yoursite.com/tags/OJ/"/>
    
      <category term="C++" scheme="http://yoursite.com/tags/C/"/>
    
  </entry>
  
  <entry>
    <title>some idea about sign out</title>
    <link href="http://yoursite.com/2019/06/04/some-idea-about-sign-out/"/>
    <id>http://yoursite.com/2019/06/04/some-idea-about-sign-out/</id>
    <published>2019-06-04T01:37:43.000Z</published>
    <updated>2019-06-04T01:37:43.130Z</updated>
    
    <summary type="html">
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Android_sharepreference_commit&amp;apply</title>
    <link href="http://yoursite.com/2019/06/03/Android-sharepreference-commit-apply/"/>
    <id>http://yoursite.com/2019/06/03/Android-sharepreference-commit-apply/</id>
    <published>2019-06-03T07:11:56.000Z</published>
    <updated>2019-06-03T07:17:58.750Z</updated>
    
    <content type="html"><![CDATA[<p>转载自<a href="https://blog.csdn.net/jake9602/article/details/18414841" target="_blank" rel="noopener">SharedPreference.Editor的apply和commit方法异同</a><br><a id="more"></a><br>在android 中存储数据时经常用SharedPreference, 并且在提交数据时一直用的是Editor的commit方法, 今天无意了看到了系统用了apply,看了方法的介绍, 原来这个方法也是可以提交数据的.<br>apply方法在官方SDK说明如下：  </p><blockquote><p>Commit your preferences changes back from this Editor to the SharedPreferences object it is editing. This atomically performs the requested modifications, replacing whatever is currently in the SharedPreferences.<br>Note that when two editors are modifying preferences at the same time, the last one to call apply wins.<br>Unlike commit, which writes its preferences out to persistent storage synchronously, apply commits its changes to the in-memory SharedPreferences immediately but starts an asynchronous commit to disk and you won’t be notified of any failures. If another editor on this SharedPreferences does a regular commit while a apply is still outstanding, the commit will block until all async commits are completed as well as the commit itself.<br>As SharedPreferences instances are singletons within a process, it’s safe to replace any instance of commit with apply if you were already ignoring the return value.<br>You don’t need to worry about Android component lifecycles and their interaction with apply() writing to disk. The framework makes sure in-flight disk writes from apply() complete before switching states.<br>The SharedPreferences.Editor interface isn’t expected to be implemented directly. However, if you previously did implement it and are now getting errors about missing apply(), you can simply call commit from apply().    </p></blockquote><p>这两个方法的区别在于： </p><ol><li>apply没有返回值而commit返回boolean表明修改是否提交成功 </li><li>apply是将修改数据原子提交到内存, 而后异步真正提交到硬件磁盘, 而commit是同步的提交到硬件磁盘，因此，在多个并发的提交commit的时候，他们会等待正在处理的commit保存到磁盘后在操作，从而降低了效率。而apply只是原子的提交到内容，后面有调用apply的函数的将会直接覆盖前面的内存数据，这样从一定程度上提高了很多效率。 </li><li>apply方法不会提示任何失败的提示。<br>由于在一个进程中，sharedPreference是单实例，一般不会出现并发冲突，如果对提交的结果不关心的话，建议使用apply，当然需要确保提交成功且有后续操作的话，还是需要用commit的。</li></ol>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;转载自&lt;a href=&quot;https://blog.csdn.net/jake9602/article/details/18414841&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;SharedPreference.Editor的apply和commit方法异同&lt;/a&gt;&lt;br&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Android" scheme="http://yoursite.com/categories/Android/"/>
    
      <category term="sharedpreference" scheme="http://yoursite.com/categories/Android/sharedpreference/"/>
    
    
      <category term="Android" scheme="http://yoursite.com/tags/Android/"/>
    
  </entry>
  
  <entry>
    <title>leetcode-26-删除相同元素</title>
    <link href="http://yoursite.com/2019/06/02/leetcode-08-%E5%88%A0%E9%99%A4%E7%9B%B8%E5%90%8C%E5%85%83%E7%B4%A0/"/>
    <id>http://yoursite.com/2019/06/02/leetcode-08-删除相同元素/</id>
    <published>2019-06-02T14:46:54.000Z</published>
    <updated>2019-06-03T07:17:28.234Z</updated>
    
    <content type="html"><![CDATA[<p>给定一个排序数组，你需要在原地删除重复出现的元素，使得每个元素只出现一次，返回移除后数组的新长度。</p><p>不要使用额外的数组空间，你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。<br><a id="more"></a></p><p>示例 1:</p><blockquote><p>给定数组 nums = [1,1,2], </p></blockquote><blockquote><p>函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 </p></blockquote><blockquote><p>你不需要考虑数组中超出新长度后面的元素。</p></blockquote><p>示例 2:</p><blockquote><p>给定 nums = [0,0,1,1,1,2,2,3,3,4],</p></blockquote><blockquote><p>函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。</p></blockquote><blockquote><p>你不需要考虑数组中超出新长度后面的元素。</p></blockquote><p><strong>说明:</strong></p><p><em>为什么返回数值是整数，但输出的答案是数组呢?</em></p><p><em>请注意，输入数组是以“引用”方式传递的，这意味着在函数里修改输入数组对于调用者是可见的。</em></p><p><em>你可以想象内部操作如下:</em><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">// nums 是以“引用”方式传递的。也就是说，不对实参做任何拷贝</span><br><span class="line">int len = removeDuplicates(nums);</span><br><span class="line"></span><br><span class="line">// 在函数里修改输入数组对于调用者是可见的。</span><br><span class="line">// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。</span><br><span class="line">for (int i = 0; i &lt; len; i++) &#123;</span><br><span class="line">    print(nums[i]);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><h2 id="Java代码"><a href="#Java代码" class="headerlink" title="Java代码"></a>Java代码</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">class Solution &#123;</span><br><span class="line">    public int removeDuplicates(int[] nums) &#123;</span><br><span class="line">        if( nums.length == 0)&#123;</span><br><span class="line">            return 0;</span><br><span class="line">        &#125;</span><br><span class="line">        int i = 0;</span><br><span class="line">        for( int j = 1; j &lt; nums.length; j++)&#123;</span><br><span class="line">            if( nums[j] != nums[i] )&#123;</span><br><span class="line">                i++;</span><br><span class="line">                nums[i] = nums[j];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        return i+1;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>我们以一个整型数组为例</p><blockquote><p>1 2 2 3 4</p></blockquote><p>传入的为数组的引用，所以更改对用户是可见的</p><ul><li>如果长度为零，直接返回零</li><li>如果不为零，i = 0；进入循环 j = 1;<ul><li>nums[j] = 2,nums[j] != nums[i] <ul><li>i++ 变成了1；</li><li>nums[i] = nums[j] = 2;</li></ul></li></ul></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;给定一个排序数组，你需要在原地删除重复出现的元素，使得每个元素只出现一次，返回移除后数组的新长度。&lt;/p&gt;
&lt;p&gt;不要使用额外的数组空间，你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。&lt;br&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Leetcode" scheme="http://yoursite.com/categories/Leetcode/"/>
    
      <category term="删除相同元素" scheme="http://yoursite.com/categories/Leetcode/%E5%88%A0%E9%99%A4%E7%9B%B8%E5%90%8C%E5%85%83%E7%B4%A0/"/>
    
    
      <category term="Java" scheme="http://yoursite.com/tags/Java/"/>
    
  </entry>
  
  <entry>
    <title>Green公式</title>
    <link href="http://yoursite.com/2019/05/25/Green%E5%85%AC%E5%BC%8F/"/>
    <id>http://yoursite.com/2019/05/25/Green公式/</id>
    <published>2019-05-25T10:37:13.000Z</published>
    <updated>2019-05-25T10:37:13.326Z</updated>
    
    <summary type="html">
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>leetcode_合并链表</title>
    <link href="http://yoursite.com/2019/05/24/leetcode-%E5%90%88%E5%B9%B6%E9%93%BE%E8%A1%A8/"/>
    <id>http://yoursite.com/2019/05/24/leetcode-合并链表/</id>
    <published>2019-05-24T11:29:50.000Z</published>
    <updated>2019-05-25T10:27:02.465Z</updated>
    
    <content type="html"><![CDATA[<p>21.将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。<br>示例：  </p><blockquote><p>输入：1-&gt;2-&gt;4, 1-&gt;3-&gt;4<br>输出：1-&gt;1-&gt;2-&gt;3-&gt;4-&gt;4</p></blockquote><p>（友情链接 —&gt;<a href="https://www.cnblogs.com/ysocean/p/7928988.html" target="_blank" rel="noopener">Java数据结构和算法（七）——链表 </a>)<br><a id="more"></a></p><p>首先先看看怎么做这道题<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * Definition for singly-linked list.</span><br><span class="line"> * public class ListNode &#123;</span><br><span class="line"> *     int val;</span><br><span class="line"> *     ListNode next;</span><br><span class="line"> *     ListNode(int x) &#123; val = x; &#125;</span><br><span class="line"> * &#125;</span><br><span class="line"> */</span><br><span class="line">class Solution &#123;</span><br><span class="line">    public ListNode mergeTwoLists(ListNode l1, ListNode l2) &#123;</span><br><span class="line">        if(l2 == null)&#123;</span><br><span class="line">            return l1;</span><br><span class="line">        &#125;</span><br><span class="line">        if(l1 == null)&#123;</span><br><span class="line">            return l2;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        ListNode temp;</span><br><span class="line">        </span><br><span class="line">        </span><br><span class="line">            if (l1.val &lt; l2.val)&#123;</span><br><span class="line">                temp = l1;</span><br><span class="line">                temp.next = mergeTwoLists(l1.next,l2);</span><br><span class="line">            &#125;else&#123;</span><br><span class="line">                temp = l2;</span><br><span class="line">                temp.next = mergeTwoLists(l1,l2.next);</span><br><span class="line">            &#125;</span><br><span class="line">      </span><br><span class="line">        </span><br><span class="line">        return temp;</span><br><span class="line">    </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><p>首先我们要知道Java链表是个啥玩意，先看个实例：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br></pre></td><td class="code"><pre><span class="line">import javax.xml.soap.Node;</span><br><span class="line"></span><br><span class="line">public class SingleLinkedList &#123;</span><br><span class="line"></span><br><span class="line">private int size;</span><br><span class="line">private Node head;</span><br><span class="line"></span><br><span class="line">public SingleLinkedList() &#123;</span><br><span class="line">size = 0;</span><br><span class="line">head = null;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">//链表的每个节点类</span><br><span class="line">private class Node&#123;</span><br><span class="line">private Object data;</span><br><span class="line">private Node next;</span><br><span class="line"></span><br><span class="line">public Node(Object data) &#123;</span><br><span class="line">this.data = data;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">//在链表头添加元素</span><br><span class="line">public Object addHead(Object obj) &#123;</span><br><span class="line">Node newHead = new Node(obj);</span><br><span class="line">if(size == 0) &#123;</span><br><span class="line">head = newHead;</span><br><span class="line">&#125;else &#123;</span><br><span class="line">newHead.next = head;</span><br><span class="line">head = newHead;</span><br><span class="line">&#125;</span><br><span class="line">size++;</span><br><span class="line">return obj;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">//在链表头删除元素</span><br><span class="line">public Object deleteHead() &#123;</span><br><span class="line">Object obj = head.data;</span><br><span class="line">head = head.next;</span><br><span class="line">size--;</span><br><span class="line">return obj;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">//查找指定元素，找到了返回Node,找不到返回null</span><br><span class="line">public Node find(Object obj) &#123;</span><br><span class="line">Node current = head;</span><br><span class="line">int tempSize = size;</span><br><span class="line">while(tempSize &gt; 0) &#123;</span><br><span class="line">if (obj.equals(current.data)) &#123;</span><br><span class="line">return current;</span><br><span class="line">&#125;else &#123;</span><br><span class="line">current = current.next;</span><br><span class="line">&#125;</span><br><span class="line">tempSize--;</span><br><span class="line">&#125;</span><br><span class="line">return null;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">//删除指定的元素，删除成功返回true</span><br><span class="line">public boolean delete(Object value) &#123;</span><br><span class="line">if(size == 0) &#123;</span><br><span class="line">return false;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">Node current = head;</span><br><span class="line">Node previous = head;</span><br><span class="line">while(current.data != value) &#123;</span><br><span class="line">if(current.next == null) &#123;</span><br><span class="line">return false;</span><br><span class="line">&#125;else &#123;</span><br><span class="line">previous = current;</span><br><span class="line">current = current.next;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">if(current == head) &#123;</span><br><span class="line">head = current.next;</span><br><span class="line">size--;</span><br><span class="line">&#125;else &#123;</span><br><span class="line">previous.next = current.next;</span><br><span class="line">size--;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">return true;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">//判断链表是否为空</span><br><span class="line">public boolean isEmpty() &#123;</span><br><span class="line">return (size == 0);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">//显示节点信息</span><br><span class="line">public void display() &#123;</span><br><span class="line">if (size &gt; 0) &#123;</span><br><span class="line">Node node = head;</span><br><span class="line">int tempSize = size;</span><br><span class="line">if(tempSize == 1) &#123;//当前链表只有一个节点</span><br><span class="line">System.out.println(&quot;[&quot;+node.data+&quot;]&quot;);</span><br><span class="line">return;</span><br><span class="line">&#125;</span><br><span class="line">while(tempSize &gt; 0) &#123;</span><br><span class="line">if(node.equals(head)) &#123;</span><br><span class="line">    System.out.print(&quot;[&quot;+node.data+&quot;-&gt;&quot;);</span><br><span class="line">&#125;else if(node.next == null) &#123;</span><br><span class="line">System.out.print(node.data+&quot;]&quot;);</span><br><span class="line">&#125;else &#123;</span><br><span class="line">System.out.print(node.data+&quot;-&gt;&quot;);</span><br><span class="line">&#125;</span><br><span class="line">node = node.next;</span><br><span class="line">tempSize--;</span><br><span class="line">&#125;</span><br><span class="line">System.out.println();</span><br><span class="line">&#125;else &#123;</span><br><span class="line">System.out.println(&quot;[]&quot;);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><h2 id="定义"><a href="#定义" class="headerlink" title="定义"></a>定义</h2><blockquote><p>链表（Linked list）是一种常见的基础数据结构，是一种线性表，但是并不会按线性的顺序存储数据，而是在每一个节点里存到下一个节点的指针(Pointer)。<br>　　使用链表结构可以克服数组链表需要预先知道数据大小的缺点，链表结构可以充分利用计算机内存空间，实现灵活的内存动态管理。但是链表失去了数组随机读取的优点，同时链表由于增加了结点的指针域，空间开销比较大。</p></blockquote><h2 id="单链表-我这种菜鸡只能谈论这种最简单的链表了"><a href="#单链表-我这种菜鸡只能谈论这种最简单的链表了" class="headerlink" title="单链表(我这种菜鸡只能谈论这种最简单的链表了)"></a>单链表(我这种菜鸡只能谈论这种最简单的链表了)</h2><blockquote><p>单链表是链表中结构最简单的。一个单链表的节点(Node)分为两个部分，第一个部分(data)保存或者显示关于节点的信息，另一个部分存储下一个节点的地址。最后一个节点存储地址的部分指向空值。<br>　　单向链表只可向一个方向遍历，一般查找一个节点的时候需要从第一个节点开始每次访问下一个节点，一直访问到需要的位置。而插入一个节点，对于单向链表，我们只提供在链表头插入，只需要将当前插入的节点设置为头节点，next指向原头节点即可。删除一个节点，我们将该节点的上一个节点的next指向该节点的下一个节点。</p></blockquote><h2 id="关于本题"><a href="#关于本题" class="headerlink" title="关于本题"></a>关于本题</h2><p>那么结合本题，我们可以从题意中得知，要把valu小的放在前。</p><ul><li>第一步，传进两个链表</li><li>第二步，判断哪个是空，一个空，返回另一个</li><li>第三步，声明一个新的链表temp作为中间链表<ul><li>如果l1.valu &lt; l2.valu <ul><li>temp = l1</li><li>temp.next的地址则需要通过递归进行新一轮的比较，所以temp.next = mergeTowLists(l1.next, l2)<br>……</li></ul></li><li>else<ul><li>temp = l2</li><li>temp.next的地址则需要通过递归进行新一轮的比较，So, temp.next = mergeTowLists(l1, l2.next)<br>……</li></ul></li></ul></li><li>第四步，以上递归进行完了，就可以将最终的temp返回了。</li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;21.将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。&lt;br&gt;示例：  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;输入：1-&amp;gt;2-&amp;gt;4, 1-&amp;gt;3-&amp;gt;4&lt;br&gt;输出：1-&amp;gt;1-&amp;gt;2-&amp;gt;3-&amp;gt;4-&amp;gt;4&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;（友情链接 —&amp;gt;&lt;a href=&quot;https://www.cnblogs.com/ysocean/p/7928988.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Java数据结构和算法（七）——链表 &lt;/a&gt;)&lt;br&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Leetcode" scheme="http://yoursite.com/categories/Leetcode/"/>
    
      <category term="合并链表" scheme="http://yoursite.com/categories/Leetcode/%E5%90%88%E5%B9%B6%E9%93%BE%E8%A1%A8/"/>
    
    
      <category term="Leetcode" scheme="http://yoursite.com/tags/Leetcode/"/>
    
      <category term="java" scheme="http://yoursite.com/tags/java/"/>
    
  </entry>
  
  <entry>
    <title>leetcode_最长公共前缀</title>
    <link href="http://yoursite.com/2019/05/18/leetcode-%E6%9C%80%E9%95%BF%E5%85%AC%E5%85%B1%E5%89%8D%E7%BC%80/"/>
    <id>http://yoursite.com/2019/05/18/leetcode-最长公共前缀/</id>
    <published>2019-05-18T04:00:21.000Z</published>
    <updated>2019-05-19T06:09:31.052Z</updated>
    
    <content type="html"><![CDATA[<p>编写一个函数来查找字符串数组中的最长公共前缀。<br>如果不存在公共前缀，返回空字符串 “”。  </p><blockquote><p>示例 1:<br>输入: [“flower”,”flow”,”flight”]<br>输出: “fl”  </p></blockquote><blockquote><p>示例 2:<br>输入: [“dog”,”racecar”,”car”]<br>输出: “”<br>解释: 输入不存在公共前缀。  </p></blockquote><a id="more"></a><h1 id="Java"><a href="#Java" class="headerlink" title="Java"></a>Java</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">class Solution&#123;</span><br><span class="line">    public String maxCommon(String[] s)&#123;</span><br><span class="line">        if ( s.length == 0 )&#123;</span><br><span class="line">            return &quot;&quot;;</span><br><span class="line">        &#125;</span><br><span class="line">        String len = s[0];</span><br><span class="line">        for ( int i = 1; i &lt; s.length; i++)&#123;</span><br><span class="line">           while( s[i].indexOf(len) != 0 )&#123;</span><br><span class="line">                len = len.substring(0, len.length() - 1);</span><br><span class="line">                if(len.isEmpty())&#123;</span><br><span class="line">                    return &quot;&quot;;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        return len;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="先看看是不是空的"><a href="#先看看是不是空的" class="headerlink" title="先看看是不是空的"></a>先看看是不是空的</h2><p>如果s根本就没有任何数据，那还判断毛线？直接返回个空字符串就行了呗；</p><h2 id="找一个串当基础"><a href="#找一个串当基础" class="headerlink" title="找一个串当基础"></a>找一个串当基础</h2><p>反正是找公共前缀，那么这个公共前缀一定存在于每个串中。那么我就拿第一个字符串s[0]当一个基础，声明一个字符串len,等于s[0];</p><h2 id="循环判断"><a href="#循环判断" class="headerlink" title="循环判断"></a>循环判断</h2><p>从第二个字符串开始，进行判断。利用indesOf()方法，看看len是不是在s[i]字符串中并且是不是从0下标开始的。</p><ul><li>如果是，终止while循环</li><li>如果不是，那就让len减去最后一个字符，继续循环。<ul><li>如果一直循环到len人家一点不剩了，s[i]里面还是没有跟它一致的，那凉了，这几个字符串没有公共前缀。返回空字符串。<h2 id="一直循环下去"><a href="#一直循环下去" class="headerlink" title="一直循环下去"></a>一直循环下去</h2>最后返回len就可以了。</li></ul></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;编写一个函数来查找字符串数组中的最长公共前缀。&lt;br&gt;如果不存在公共前缀，返回空字符串 “”。  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;示例 1:&lt;br&gt;输入: [“flower”,”flow”,”flight”]&lt;br&gt;输出: “fl”  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;示例 2:&lt;br&gt;输入: [“dog”,”racecar”,”car”]&lt;br&gt;输出: “”&lt;br&gt;解释: 输入不存在公共前缀。  &lt;/p&gt;
&lt;/blockquote&gt;
    
    </summary>
    
      <category term="Leetcode" scheme="http://yoursite.com/categories/Leetcode/"/>
    
      <category term="最长公共前缀" scheme="http://yoursite.com/categories/Leetcode/%E6%9C%80%E9%95%BF%E5%85%AC%E5%85%B1%E5%89%8D%E7%BC%80/"/>
    
    
      <category term="Java" scheme="http://yoursite.com/tags/Java/"/>
    
      <category term="Leetcode" scheme="http://yoursite.com/tags/Leetcode/"/>
    
  </entry>
  
  <entry>
    <title>leetcode_整数转罗马数字</title>
    <link href="http://yoursite.com/2019/05/16/leetcode-%E6%95%B4%E6%95%B0%E8%BD%AC%E7%BD%97%E9%A9%AC%E6%95%B0%E5%AD%97/"/>
    <id>http://yoursite.com/2019/05/16/leetcode-整数转罗马数字/</id>
    <published>2019-05-16T09:46:42.000Z</published>
    <updated>2019-05-16T13:50:35.699Z</updated>
    
    <content type="html"><![CDATA[<p>罗马数字包含以下七种字符： I， V， X， L，C，D 和 M。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">字符          数值</span><br><span class="line">I             1</span><br><span class="line">V             5</span><br><span class="line">X             10</span><br><span class="line">L             50</span><br><span class="line">C             100</span><br><span class="line">D             500</span><br><span class="line">M             1000</span><br></pre></td></tr></table></figure></p><a id="more"></a><p>通常情况下，罗马数字中小的数字在大的数字的右边。但也存在特例，例如 4 不写做 IIII，而是 IV。数字 1 在数字 5 的左边，所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地，数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况：</p><ul><li>I 可以放在 V (5) 和 X (10) 的左边，来表示 4 和 9。</li><li>X 可以放在 L (50) 和 C (100) 的左边，来表示 40 和 90。 </li><li>C 可以放在 D (500) 和 M (1000) 的左边，来表示 400 和 900。 </li></ul><p>给定一个整数，将其转为罗马数字。输入确保在 1 到 3999 的范围内。</p><h2 id="Java"><a href="#Java" class="headerlink" title="Java"></a>Java</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">class Solution &#123;</span><br><span class="line">    public String intToRoman(int num) &#123;</span><br><span class="line"></span><br><span class="line">        //create an unique dictionary</span><br><span class="line"></span><br><span class="line">        int [] values= &#123;1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1&#125;;</span><br><span class="line">        String[]  rom= &#123;&quot;M&quot;, &quot;CM&quot;, &quot;D&quot;, &quot;CD&quot;, &quot;C&quot;, &quot;XC&quot;, &quot;L&quot;, &quot;XL&quot;, &quot;X&quot;, &quot;IX&quot;, &quot;V&quot;, &quot;IV&quot;, &quot;I&quot;&#125;;</span><br><span class="line">        int a;</span><br><span class="line">        StringBuilder str = new StringBuilder();</span><br><span class="line">        for ( int i = 0; i &lt; values.length; i++) &#123;</span><br><span class="line">            a = num / values[i];</span><br><span class="line">            if ( a == 0) &#123;</span><br><span class="line">                continue;</span><br><span class="line">            &#125;</span><br><span class="line">            for ( int j = a; j &gt; 0; j--)&#123;</span><br><span class="line">                str.append(rom[i]);</span><br><span class="line">            &#125;</span><br><span class="line">            num = num - values[i] * a;</span><br><span class="line">            if ( num == 0)&#123;</span><br><span class="line">                break;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        return str.toString();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="这个代码有几点很关键"><a href="#这个代码有几点很关键" class="headerlink" title="这个代码有几点很关键"></a>这个代码有几点很关键</h2><ul><li>创建字典</li><li>a 的使用</li></ul><p>创建字典大家应该都很清楚，一个数组和一个字符串数组，两者的下标对应；</p><h2 id="接下来就是重点了："><a href="#接下来就是重点了：" class="headerlink" title="接下来就是重点了："></a>接下来就是重点了：</h2><p>咱们先拿一个数当例子 比如58</p><ul><li>总共就这几个罗马数字，先从大到小遍历。</li><li>58 / 1000 ？不行，1000太大，58承受不住；900 ？ 500？ 90？ 50？ 停，50可以哎，先把 L 选上。 几个L？<code>a = num / values[i] = 1</code>, 一个，好，那就先用str.append()方法把i下标对应的罗马数字加到str里面。</li><li>58 里已经确定有一个L了，还剩下多少？<code>num - a * values[i] = 8</code>，</li><li>继续轮回，40？ 10？ 9？ 5可以，<code>a = num / values[i] = 1</code>，再追加一个V。现在是LV了,还剩<code>num = num - a * values[i] = 3</code>。</li><li>最后一轮，<code>a = num / values[i] = 3</code>， 再追加三个I。即 LVIII；</li></ul><h2 id="最后很重要的一点，返回的是str-toString"><a href="#最后很重要的一点，返回的是str-toString" class="headerlink" title="最后很重要的一点，返回的是str.toString()"></a>最后很重要的一点，返回的是str.toString()</h2>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;罗马数字包含以下七种字符： I， V， X， L，C，D 和 M。&lt;br&gt;&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;字符          数值&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;I             1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;V             5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;X             10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;L             50&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;C             100&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;D             500&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;M             1000&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Leetcode" scheme="http://yoursite.com/categories/Leetcode/"/>
    
      <category term="整数转罗马数字" scheme="http://yoursite.com/categories/Leetcode/%E6%95%B4%E6%95%B0%E8%BD%AC%E7%BD%97%E9%A9%AC%E6%95%B0%E5%AD%97/"/>
    
    
      <category term="Java" scheme="http://yoursite.com/tags/Java/"/>
    
      <category term="leetcode" scheme="http://yoursite.com/tags/leetcode/"/>
    
  </entry>
  
  <entry>
    <title>leetcode_有效括号</title>
    <link href="http://yoursite.com/2019/05/16/leetcode-%E6%9C%89%E6%95%88%E6%8B%AC%E5%8F%B7/"/>
    <id>http://yoursite.com/2019/05/16/leetcode-有效括号/</id>
    <published>2019-05-16T05:47:11.000Z</published>
    <updated>2019-05-16T05:51:15.026Z</updated>
    
    <content type="html"><![CDATA[<p>给定一个只包括 ‘(‘，’)’，’{‘，’}’，’[‘，’]’ 的字符串，判断字符串是否有效。<br>有效字符串需满足：<br>左括号必须用相同类型的右括号闭合。<br>左括号必须以正确的顺序闭合。<br>注意空字符串可被认为是有效字符串。<br><a id="more"></a></p><blockquote><p>示例 1:<br>输入: “()”<br>输出: true  </p></blockquote><blockquote><p>示例 2:<br>输入: “()[]{}”<br>输出: true  </p></blockquote><blockquote><p>示例 3:<br>输入: “(]”<br>输出: false  </p></blockquote><blockquote><p>示例 4:<br>输入: “([)]”<br>输出: false  </p></blockquote><blockquote><p>示例 5:<br>输入: “{[]}”<br>输出: true  </p></blockquote><h1 id="Java"><a href="#Java" class="headerlink" title="Java"></a>Java</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line">class Solution&#123;</span><br><span class="line"></span><br><span class="line">     public boolean isValid(String s)&#123;</span><br><span class="line">         Stack&lt;Character&gt; stack = new Stack&lt;Character&gt;;</span><br><span class="line">         for (char alp : s.toCharArray())&#123;</span><br><span class="line">             if(alp == &apos;(&apos; )&#123;</span><br><span class="line">                 stack.push(&apos;)&apos;);</span><br><span class="line">             &#125;else if(alp == &apos;&#123;&apos;)&#123;</span><br><span class="line">                 stack.push(&apos;&#125;&apos;);</span><br><span class="line">             &#125;else if(alp == &apos;[&apos;)&#123;</span><br><span class="line">                 stack.push(&apos;]&apos;);</span><br><span class="line">             &#125;else if(stack.isEmpty()||stack.pop()!= alp)&#123;</span><br><span class="line">                 return false;</span><br><span class="line">             &#125;</span><br><span class="line">         &#125;</span><br><span class="line">         return stack.isEmpty();</span><br><span class="line">     &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>代码不长，一点一点看 </p><h2 id="首先，建立一个栈实例stack"><a href="#首先，建立一个栈实例stack" class="headerlink" title="首先，建立一个栈实例stack"></a>首先，建立一个栈实例stack</h2><p>记住他是后进先出<br>不了解Stack和Character的同学请点击<br>–&gt;<a href="http://www.runoob.com/java/java-stack-class.html" target="_blank" rel="noopener">Stack类</a><br>–&gt;<a href="http://www.runoob.com/java/java-character.html" target="_blank" rel="noopener">Character类</a></p><p>有了一个栈，我们就有空去装东西了。</p><h2 id="遍历"><a href="#遍历" class="headerlink" title="遍历"></a>遍历</h2><p>for循环里进行遍历，我们首先假设这个字符串是”( ( ( { } ) ) ) }”,那么结合实例，接下来代码的主要思想是：</p><ul><li>如果我遇到一个左括号，就往栈里加一个与这对应的右括号</li><li>如果是右括号，比如第五个括号，那么就跟栈顶元素对比并且顶部元素出栈（栈是后进先出的，第五个括号是跟第四个对应的，所以遍历到第四个时往栈里添加的括号按照常理应该是跟第五个一样的）<ul><li>如果对比不一样，false</li></ul></li><li>由于对比一次就出栈一次，如果出完了，stack说自己一滴都不剩了，可alp居然还在遍历，有问题，原来的字符串绝对是奇数个字符，false</li><li>如果运行到最后，没啥问题，判断stack,如果还剩元素，说明原来的右括号比左括号少，直接返回stack.isEmpty()就行了。</li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;给定一个只包括 ‘(‘，’)’，’{‘，’}’，’[‘，’]’ 的字符串，判断字符串是否有效。&lt;br&gt;有效字符串需满足：&lt;br&gt;左括号必须用相同类型的右括号闭合。&lt;br&gt;左括号必须以正确的顺序闭合。&lt;br&gt;注意空字符串可被认为是有效字符串。&lt;br&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Leetcode" scheme="http://yoursite.com/categories/Leetcode/"/>
    
      <category term="有效括号" scheme="http://yoursite.com/categories/Leetcode/%E6%9C%89%E6%95%88%E6%8B%AC%E5%8F%B7/"/>
    
    
      <category term="Java" scheme="http://yoursite.com/tags/Java/"/>
    
  </entry>
  
  <entry>
    <title>Android-px_dp</title>
    <link href="http://yoursite.com/2019/04/20/Android-px-dp/"/>
    <id>http://yoursite.com/2019/04/20/Android-px-dp/</id>
    <published>2019-04-20T13:16:10.000Z</published>
    <updated>2019-05-06T13:45:28.942Z</updated>
    
    <summary type="html">
    
    </summary>
    
    
      <category term="Android" scheme="http://yoursite.com/tags/Android/"/>
    
  </entry>
  
</feed>
