精华内容
下载资源
问答
  • 数学闭区间和开区间的区别是什么

    千次阅读 2016-11-04 09:32:09
    1)满足 a ≤ x ≤ b 实数 x 的集合, 表示为 [ a,b ],叫做闭区间; 2)满足 a 实数 x 的集合, 表示为 ( a,b ),叫做开区间; 3)满足 a ≤ x ,a ≤ b 实数 x 的集合, 分别表示为 [ a,b ),( a,b ],叫做半开...
    设 a,b 是两个实数,且 a ≤ b.
    1)满足 a ≤ x ≤ b 的实数 x 的集合,
    表示为 [ a,b ],叫做闭区间;
    2)满足 a < x <b 的实数 x 的集合,
    表示为 ( a,b ),叫做开区间;
    3)满足 a ≤ x <b,a <x ≤ b 的实数 x 的集合,
    分别表示为 [ a,b ),( a,b ],叫做半开区间.
    这里实数 a,b 叫做区间的端点.
    从上边的三个定义你就可以看出来,闭区间是有a,b两个端点的.
    展开全文
  • 存储区间是连续,占用内存严重,所以空间复杂度很大,为o(n),但是数组二分查找时间复杂度很小为o(1)。 特点是大小固定,不可变,在同一个数组中只能存放同一个类型数据,寻址容易,插入删除困难。 链表...

    数组和链表

    1. 数组:所谓数组就是相同数据类型的元素按照一定顺序排列的集合。
      它的存储区间是连续的,占用内存严重,所以空间复杂度很大,为o(n),但是数组的二分查找时间复杂度很小为o(1)。
      特点是大小固定,不可变,在同一个数组中只能存放同一个类型的数据,寻址容易,插入和删除困难。
    2. 链表:所谓链表就是一种物理存储单元上非连续的,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针实现的。链表是由一系列节点(链表中每个元素称为节点)组成的,节点是可以动态生成的。每个节点包括两部分:一个是存储数据元素的数据域,另一个是存储下一个节点地址的指针域。
      链表的特点:链表存储区间离散,占用内存较少,所以空间复杂度小,但是时间复杂度大o(n),寻址困难,但是插入和删除元素很容易。
    3. 集合:可以操作数量可变和类型不同的一组数据。所有的java集合都在java.util包中,java集合只能存放引用类型的数据,不能存放基本类型数据。

    ArrayList的底层实现方式

    1. ArrayList底层是通过数组实现的,实例化ArrayList无参构造函数默认数组初始化长度为10。
    2. add方法底层实现如果增加的元素个数超过了10个,那么ArrayList底层会新生成一个数组,长度变为原数组的1.5倍+1,然后将原始数组的元素复制到新数组中,并且后续增加的元素都会放到新数组中。当新数组也无法满足元素大小时,继续重复这个扩容的过程。只要元素长度超过了容量就开始扩容。扩容数组调用的方法为ArrayList.copyOf(objArr,objArr.length+1)。

    ArrayList和Vector的区别

    ArrayList和vector都实现了list接口(list接口继承了collection接口),他们都是有序集合,并且允许有重复的元素存在。他们相当于是一种动态的数组,所以可以通过下标的方式取出某一个元素。
    他们的区别主要体现在以下两个方面:

    1. 同步性
      vector是线程安全的,也就是说它的方法之间是线程同步的,而ArrayList是线程不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那么可以使用ArrayList,因为它不考虑线程安全问题,效率比较高。如果多个线程要访问到集合,那么最好是用vector,因为它是线程安全的,不用我们去考虑线程问题。
    2. 数据增长策略
      ArrayList和vector都有一个初始容量大小,当数据长度超过了这个容量大小就需要扩容。vector默认增长为原来数据长度的2倍,而ArrayList是增长为原来的1.5倍。
      ArrayList和vector都可以设置初始空间的大小,此外vector还可以设置增长的空间大小,而ArrayList没有提供设置增长空间的方法。

    LinkedList的底层实现方式

    linkedlist底层的数据结构是基于双向循环链表实现的,并且头结点中不存放数据。
    如下图(图太丑了,将就着看,不讲究了):
    1320926-20190701205336761-701338084.png

    hashmap的底层实现原理

    hashmap是map集合的实现类之一,
    它的特点有:

    1. 以键值对的形式存储值
    2. 键不能重复而值可以重复
    3. 允许有null的键和值
    4. 并且线程不安全所以效率很快,方法也不是同步的。
      hashmap是基于hashing原理,用put(key,value)存储对象到hashmap中,使用get(key)从hashmap中获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashcode()方法来计算hashcode,然后找到bucket位置来存储值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。hashmap是在bucket中存储键对象和值对象的。
      如果hashmap的大小超过了负载因子(load factor)定义的容量(默认为0.75),它将会像其他集合类一样采取扩容,将会创建原来hashmap大小2倍的bucket数组,来重新调整map的大小,并且将原来的对象放入新的bucket数组中。这个过程叫做rehashing。因为它会调用hash方法找到新的bucket数组位置。hashmap使用链表来解决碰撞问题,当发生了碰撞,对象将会存储在链表的下一个节点中。hashmap在每个链表节点中存储键值对对象。
      详情参见:https://www.cnblogs.com/java-jun-world2099/p/9258605.html

    hashmap和hashtable的区别

    1. hashmap是线程不安全的,允许有null的键和值,效率较高,方法不是Synchronize的需要提供外同步,它有containsvalue和containskey方法。
    2. hashtable是线程安全的,不允许有null的键和值,效率低下,方法是同步的,它有containsvalue和containskey方法。

    List,Set,Map的区别

    java中的集合包括三大类,分别为list,set,map,他们都处于java.util包中,list,set,map都是接口,他们都有各自的实现类。set的实现类主要hashSet和treeSet,list的实现类主要有ArrayList和linkedlist,map的主要实现类有hashMap和treeMap。如下图所示
    1320926-20190701180903252-440527548.png

    1. Set中的对象不按特定的方式排序,并且没有重复的元素。但是它的有些实现类能对集合中的对象按特定的方式排序,例如treeSet实现类,它可以按照默认排序,也可以通过java.util.Comparator接口来自定义排序方式。set有两个实现类,hashSet和treeSet,他们有一定的区别,hashSet中元素不能重复并且没有顺序,treeSet中元素不能重复但是有顺序,如果需要排序使用treeSet,不需要排序使用hashSet,它的速度比treeSet快。

    2. List中对象按照索引位置排序,可以有重复的对象。允许按照对象在集合中的索引位置来检索对象。例如通过list.get(i)的方式来获得集合中的某一个对象。
    3. Map中的每一个元素都包括一个key和value值,它是以键值对的形式存在,键值不允许重复,值可以重复。

    Set集合中的元素是不能重复的,那么用什么方法区分重复与否?是用==还是equals方法,他们有什么区别呢?

    可以参见这篇博文:https://www.cnblogs.com/qf123/p/8574582.html
    equals方法是String类从他的超类object中继承过来的,用于检测两个对象是否相等,即两个对象的内容是否相等。
    ==用于比较引用和比较基本类型时有不同的功能:

    1. 比较基本数据类型时,如果两个值相同则为true
    2. 比较引用时,如果两个引用指向内存中的同一个对象则为true。

    HashMap,LinkedHashMap和TreeMap的区别

    1. 共同点
      他们都是map的实现类。
    2. 不同点
      HashMap里面存入的键值对在取出的时候是随机的。
      TreeMap取出来的是排序后的键值对,如果需要按自然顺序或者自定义顺序键,那么TreeMap更好。
      LinkedHaspMap是HashMap的一个子类,如果需要输出的顺序和输入的顺序相同,那么可以使用LinkedHashMap实现。

    转载于:https://www.cnblogs.com/jasonboren/p/11115793.html

    展开全文
  • 对于Android开发者来说深入了解Java的集合类很有必要主要是从CollectionMap接口衍生出来,目前主要提供了List、Set Map这三大类的集合Collection接口主要有两种子类分别为ListSet,区别主要是List保存对象...

    对于Android开发者来说深入了解Java的集合类很有必要主要是从Collection和Map接口衍生出来的,目前主要提供了List、Set和 Map这三大类的集合

    Collection接口主要有两种子类分别为List和Set,区别主要是List保存的对象可以重复

    而Set不可以重复

    而Map一般为key-value这样的对应关系,比如我们常用的HashMap。


     数组

    数组存储区间是连续的,占用内存严重,故空间复杂的很大。但数组的二分查找时间复杂度小,为O(1);数组的特点是:寻址容易,插入和删除困难

    链表

    链表存储区间离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度很大,达O(N)。链表的特点是:寻址困难,插入和删除容易。

    哈希表

    那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要提起的哈希表。哈希表((Hash table既满足了数据的查找方便,同时不占用太多的内容空间,使用也十分方便。



    java中各种集合的关系图 

    Collection       接口的接口     对象的集合 
    ├ List           子接口         按进入先后有序保存   可重复 
    │├ LinkedList    接口实现类     链表     插入删除   没有同步   线程不安全 
    │├ ArrayList     接口实现类     数组     随机访问   没有同步   线程不安全 
    │└ Vector        接口实现类     数组                  同步        线程安全 
    │   └ Stack 
    └ Set            子接口       仅接收一次,并做内部排序 

    ├ HashSet 

    │   └ LinkedHashSet 
    └ TreeSet
     

    List 主要有ArrayList、LinkedList、Vector和Stack 
    一、List 主要有ArrayList、LinkedList、Vector和Stack
    有关这些子类的性能,Android开发网从插入、删除、移动等方面按照元素的执行效率做一一分析,通过分析Sun 的Java源码和实际元素操作得出下面结论:

            ArrayList -是线程不安全 底层是由数组实现 他的构造主要从AbstractList实现,主要是判断下初始元素的容量,ArrayList最大的特点就是提供了Add、Get操作,当然可以通过迭代器来遍历,对于元素的存在可以通过contains方法判断。

           LinkedList - 线程不安全的 作为一种双向链表结构,对于元素的插入、删除效率比较高,只需要调整节点指向即可,但是对于随机查找而言性能主要看这个链表长度和运气了。 LinkedList也提供了ArrayList的get方法,但是要复杂的多,主要通过next或previous方法遍历得到,LinkedList要移动指针

           Vector -线程安全的,这两个类底层都是由数组实现的,效率低  比较简单和ArrayList差不多,主要是内部实现了synchronized关键字,实现了线程安全访问但性能有些降低,同时对于元素的扩充在算法上和ArrayList稍有不同,通过构造的容量增量系数来决定。

           Stack - 作为栈的操作,本次继承于Vector,提供了push,pop和peek方法,peek是不弹出根据数据大小获取最后一个元素对象。

      二、Set 主要有HashSet 和 TreeSet 

      HashSet - 该类是从Set接口继承而来,相对于List而言就是说内部添加的元素不能重复 Hashtable 继承 Map 接口,实现一个 key-value 映射的哈希表。任何非空( non-null )的对象都可作为 key 或者 value 。 当然从名字的Hash来看就是通过哈希算法来实现防止冲突来获得防止重复的,整体上从HashMap实现,存放元素方法的也是类似key- value的对应的,通过迭代器遍历,不过HashSet不是线程安全的。 

      TreeSet - 这个相对于HashSet而言主要是提供了排序支持,TreeSet是从TreeMap类实现,也是非线程安全的。 

      可以看到Set的两个类都和Map有关,下面就一起看下有关映射(Map)相关的使用。 

      三、Map 主要有 HashMap 和 TreeMap 


    HashMap和Hashtable的区别

    HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。主要的区别有:线程安全性,同步(synchronization),以及速度。

    1. HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。
    2. HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。
    3. 另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。
    4. 由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。
    5. HashMap不能保证随着时间的推移Map中的元素次序是不变的。


      HashMap - ,可以为空,提供了比较强大的功能实现,比如说loadFactor可以控制元素增长时内存分配,HashMap也是非线程安全的。 

    原理:



    哈希表:由数组+链表组成的 


    HashMap类有一个叫做Entry的内部类。这个Entry类包含了key-value作为实例变量。我们来看下Entry类的结构。Entry类的结构:

    staticclassEntryimplementsMap.Entry
    {
            finalK key;
            V value;
            Entry next;
            finalinthash;
            ...//More code goes here
    }  

    当新建一个HashMap的时候,就会初始化一个数组

    transient Entry[] table;
    
    static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        Entry<K,V> next;
        final int hash;
        ……
    }
    可以看出,Entry就是数组中的元素,每个 Map.Entry 其实就是一个key-value对,它持有一个指向下一个元素的引用,这就构成了链表。
    

     在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。

    HashMap实现存储

     1 public V put(K key, V value) {
     2     // HashMap允许存放null键和null值。
     3     // 当key为null时,调用putForNullKey方法,将value放置在数组第一个位置。 4     if (key == null)
     5         return putForNullKey(value);
     6     // 根据key的keyCode重新计算hash值。 7     int hash = hash(key.hashCode());
     8     // 搜索指定hash值在对应table中的索引。 9     int i = indexFor(hash, table.length);
    10     // 如果 i 索引处的 Entry 不为 null,通过循环不断遍历 e 元素的下一个元素。11     for (Entry<K,V> e = table[i]; e != null; e = e.next) {
    12         Object k;
    13         if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
    14             // 如果发现已有该键值,则存储新的值,并返回原始值15             V oldValue = e.value;
    16             e.value = value;
    17             e.recordAccess(this);
    18             return oldValue;
    19         }
    20     }
    21     // 如果i索引处的Entry为null,表明此处还没有Entry。22     modCount++;
    23     // 将key、value添加到i索引处。24     addEntry(hash, key, value, i);
    25     return null;
    26 }
    复制代码

    关键方法:addEntry(hash, key, value, i);
    当我们往HashMap中put元素的时候,先根据key的hashCode重新计算hash值,根据hash值得到这个元素在数组中的位置(即下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上。


    要牢记以下关键点:

    • HashMap有一个叫做Entry的内部类,它用来存储key-value对。
    • 上面的Entry对象是存储在一个叫做table的Entry数组中
    • table的索引在逻辑上叫做“桶”(bucket),它存储了链表的第一个元素。
    •  利用key的hashCode重新hash计算出当前对象的元素在数组中的下标 
    • 存储时,如果出现hash值相同的key,此时有两种情况。(1)如果key相同,则覆盖原始值;(2)如果key不同(出现冲突),则将当前的key-value放入链表中
    • 获取时,直接找到hash值对应的下标,在进一步判断key是否相同,从而找到对应值。
    • 理解了以上过程就不难明白HashMap是如何解决hash冲突的问题,核心就是使用了数组的存储方式,然后将冲突的key的对象放入链表中,一旦发现冲突就在链表中做进一步的对比。

    •  TreeMap - 相对于HashMap它的排序可以通过传入包含comparator的属性来控制。 


    扩展类:

     LinkedHashMap 类:
     原理:双向环形链表



    accessOrder主要对双向环形链表有影响,如果是true则表示双向环形链表按照访问的顺序存储,如果是false则表示按照插入的顺序存储,区别就是如果是插入顺序则双向环形链表的结构是不变的,如果是访问顺序则每次访问的时候比如get方法就会把get到的元素从链表中删除然后重新加到链表的尾部,因为尾部表示最新加入的,删除的时候是从头部开始删除,尾部是最后删除的,符合最近使用原则,

    两个属性,nxt表示链表的下一个元素,prv表示链表的前一个元素
    知道Head:然后pre和next可以得到最新和最老的元素!

    使用ArrayMap/SparseArray而不是HashMap等传统数据结构

    最近编程时,发现一个针对HashMap<Integer, E>的一个提示:


    翻译过来就是:用SparseArray<E>来代替会有更好性能。
    那我们就来看看源码中SparseArray到底做了哪些事情:


    并发包集合类

    1). BlockingQueue

    • ArrayBlockingQueue :一个由数组支持的有界队列。
    • LinkedBlockingQueue :一个由链接节点支持的可选有界队列。
    • PriorityBlockingQueue :一个由优先级堆支持的无界优先级队列。
    • DelayQueue :一个由优先级堆支持的、基于时间的调度队列。
    • SynchronousQueue :一个利用 BlockingQueue 接口的简单聚集(rendezvous)机制。

    2).ConcurrentMap

    putIfAbsent() 方法是原子的

    等价的 putIfAbsent() 代码
      if (!map.containsKey(key)) {
        return map.put(key, value);
      } else {
        return map.get(key);
      }


    3).使用 CopyOnWriteArrayList 和 CopyOnWriteArraySet


    Evenbus源码里面有用到这个玩意

    总结:区别和比较

    5.HashMap和 HashTable 的区别:

    HashTable比较老,是基于Dictionary 类实现的,HashTable 则是基于 Map接口实现的 
    HashTable 是线程安全的, HashMap 则是线程不安全的 
    HashMap可以让你将空值作为一个表的条目的key或value




    HashMap的原理


     转载自:https://blog.csdn.net/WHB20081815/article/details/70291412
    展开全文
  • Kotlin进阶之集合与区间 ...在这之前,理解只读的可变集合与实际不变的集合的区别很有必要。两者创建都很容易,但是类型系统表达却不相同。 Kotlin的List类型是一个接口,提供只读操作如size,get等等。与Java


    集合

    与多数语言不一样,Kotlin区分可变与不可变集合(list,sets,maps等等)。精确控制什么时候可以编辑集合有利于减少BUG和设计良好的API。

    在这之前,理解只读的可变集合与实际不变的集合的区别很有必要。两者创建都很容易,但是类型系统表达却不相同。

    Kotlin的List<out T>类型是一个接口,提供只读操作如size,get等等。与Java相同,继承Collection<T>接口,Collection<T>继承Iterable<T>。MutableList<T>添加了修改数组的方法。同样模式还有Set<out T>/MutableSet<T>和Map<K, out V>/MutableMap<K, V>

    List与Set的基础用法

    val numbers: MutableList<Int> = mutableListOf(1, 2, 3)
    val readOnlyView: List<Int> = numbers
    println(numbers) // 输出"[1, 2, 3]"
    numbers.add(4)   
    println(numbers) // 输出"[1 , 2, 3, 4]"
    readOnlyView.clear() // 不会通过编译
    
    val strings = hashSetOf("a", "b", "c", "c")
    assert(strings.size == 3)
    

    Kotlin没有创建列表或Set的专用语法,可以使用如listOf(),mutableListOf(),setOf(),mutableSetOf()创建。在非性能严格的代码中,可以使用简单的惯用语法实现:mapOf(a to b, c to d)。

    readOnlyView变量指向相同list,像基本List改变一样改变。如果唯一引用指向只读变量List,则认为集合整体不可变。

    创建不可变集合的一个简单方法:

    val items = listOf(1, 2, 3)
    

    目前,listOf方法使用数组List实现,但在未来可能会返回存储效率更高的完全不可变的集合类型。

    只读类型为协变量,意味可是使用List<Rectangle>赋值给List<Shape>(假设Rectangle继承Shape)。在可变集合中则不被允许,因为在运行时,可变集合可能允许出错。

    有时希望及时返回集合快照给调用者,保证集合不变。

    class Controller {
        private val _items = mutableListOf<String>()
        val items: List<String> get() = _items.toList()
    }
    

    toList扩展函数只是List的副本,返回的List保证不会改变。

    还应该熟悉List和Set的一些有用的扩展方法

    val items = listOf(1, 2, 3, 4)
    items.first() == 1
    items.last() == 4
    items.filter { it % 2 == 0 } // 返回[2 , 4]
    
    val rwList = mutableListOf(1, 2, 3)
    rwList.requireNoNulls()        // 返回 [1, 2, 3]
    if (rwList.none { it > 6 }) println("No items above 6")  // 输出 "No items above 6"
    val item = rwList.firstOrNull()
    

    同样的还有其他如排序,压缩,折叠,减少等可能需要的实用方法。

    Map采取相同模式,可以像如下实例化和访问。

    val readWriteMap = hashMapOf("foo" to 1, "bar" to 2)
    println(readWriteMap["foo"]) // 输出"1"
    val snapshot: Map<String, Int> = HashMap(readWriteMap)
    

    区间

    使用rangeTo函数行成的区间表达式,可以使用..形式的操作符,并使用in或!in补全。Kotlin为任意比较类型定义的区间,对于整型基本类型则有自己最优化的实现。如:

    if( i in 1..10){  // 与 1 <= i && i <= 10相等
        println(i)
    }
    

    整形类型区间(IntRange,LongRange,CharRange)有个额外的特性:可以循环迭代。编译器可以将区间转为近似Java的for循环,而没有额外的开销。

    for ( i in 1..4) print(i) // 输出 "1234"
    for (i in 1..4) print(i) //  无任何输出
    

    如果希望逆序循环,可通过标准库中定义的downTo函数

    for (i in 4 downTo 1) print(i) // 输出 "4321"
    

    循环通过step函数来指定单循环步数

    for(i in 1..4 step 2) print(i) // 输出"13"
    for(i in 4 downTo 1 step 2) print(i) // 输出"42"
    

    使用until函数创建不包括结尾元素的循环迭代操作

    for( i in 1 until 10 ){ // i in [1 , 10) 不包括10
        println(i)
    }
    

    实现原理

    区间实现库中的一个通用的接口:ClosedRange<T>

    ClosedRange<T>表示数学意义上的闭合区间,为比较类型定义。有两个端点:起始和结束,两点都包含在区间内。主要操作符是contains,使用形式in和!in

    整型数列(IntProgression,LongProgression,CharProgression)表示算数队列。数列使用起始元素,末尾元素和非零步数定义。首位元素为起始元素,子队列元素为前一个元素加上步数,末尾元素总要循环命中(除非队列为空)。

    队列为Iterable<N>子类,N表示Int,Long,Char,所以可以在for循环和像map,filter等函数中使用。队列循环近似与Java中的索引for循环

    for (int i = first; i != last; i += step) {
      // ...
    }
    

    对于整型,..操作符会创建实现ClosedRange<T>和*Progression接口的对象。如IntRange实现ClosedRange<Int>并继承IntProgression,因此所有为IntProgression定义的操作符都用于IntRange。downTo()和step()函数返回值为*Progression。

    使用fromClosedRange函数构建的队列,定义在它们的伴生对象中:

    IntProgression.fromClosedRange(start, end, step)
    

    队列末尾元素用于计算查找step为正数时不超过end值的最大值,或step为负数是不小于end的最小值(last - first) % step == 0。

    工具函数

    rangeTo()

    整型的rangeTo()操作符就是调用*Range的构造方法

    class Int{
        //...
        operator fun rangeTo(other: Long): LongRange = LongRange(this, other)
        //...
        operator fun rangeTo(other: Int): IntRange = IntRange(this, other)
        //...
    }
    

    浮点数(Double,Float)没有定义rangeTo操作符,使用标准库提供的泛型Comparable类型替代。

    public operator fun <T: Comparable<T>> T.rangeTo(that: T): ClosedRange<T>
    

    这个函数的返回区间不能用于循环迭代。

    downTo()

    为整型定义的downTo() 扩展函数,如:

    fun Long.downTo(other: Int): LongProgression {
        return LongProgression.fromClosedRange(this, other.toLong(), -1L)
    }
    
    fun Byte.downTo(other: Int): IntProgression {
        return IntProgression.fromClosedRange(this.toInt(), other, -1)
    }
    

    reversed()

    为每个*Progression类定义reversed()扩展函数,返回反转的数列

    fun IntProgression.reversed(): IntProgression {
        return IntProgression.fromClosedRange(last, first, -step)
    }
    

    step()

    为*Progression定义step()扩展函数,返回使用step值过滤后的数列。step值要求总要为正数,因此这个不会修改循环方向。

    fun IntProgression.step(step: Int): IntProgression {
        if (step <= 0) throw IllegalArgumentException("Step must be positive, was: $step")
        return IntProgression.fromClosedRange(first, last, if (this.step > 0) step else -step)
    }
    
    fun CharProgression.step(step: Int): CharProgression {
        if (step <= 0) throw IllegalArgumentException("Step must be positive, was: $step")
        return CharProgression.fromClosedRange(first, last, if (this.step > 0) step else -step)
    }
    
    函数返回的数列末尾值可能会与原队列末尾值不同,保证(last - first) % step == 0。
    (1..12 step 2).last == 11  // 队列 [1, 3, 5, 7, 9, 11]
    (1..12 step 3).last == 10  // 队列 [1, 4, 7, 10]
    (1..12 step 4).last == 9   // 队列 [1, 5, 9]
    展开全文
  • 以[10,20)区间随机产生10个整数为例展示: //list :有序 可重复 public static void fun1(){ List<Integer> list = new ArrayList<Integer>(); do{ int a = (int) (Math.random(...
  • 数组存储区间是连续,占用内存严重,故空间复杂很大。但数组二分查找时间复杂度小,为O(1);数组特点是:寻址容易,插入删除困难; 链表 链表存储区间离散,占用内存比较宽松,故空间复杂度很小,但时间...
  • 数据结构之数组链表的区别

    万次阅读 2019-03-27 19:03:59
    第一题便是数据结构中的数组链表的区别 数组(Array) 一、数组特点: 所谓数组,就是相同数据类型的元素按一定顺序排列的集合;数组的存储区间是连续的,占用内存比较大,故空间复杂的很大。但数组的二分查找...
  • 集合Kotlin中,区别可变集合和不可变集合(lists,sets,maps等),不可变集合只提供了有关读api,没有编辑api,如果我们要修改集合,只能通过可变集合去修改。这样设计有助于我们降低bug设计良好api。fun ...
  • 数组链表的区别

    2020-06-01 17:39:07
    数组存储区间是连续,占用内存比较大,故空间复杂很大。但数组二分查找时间复杂度小,都是O(1);数组特点是:查询简单,增加删除困难; 1.1 在内存中,数组是一块连续区域 1.2 数组需要预留空间 在...
  • 众所周知,HashMap 是一个用于存储Key-Value键值对的集合,每一个键值对也叫做 Entry。 这些个键值对(Entry)分散存储在一个数组当中,这个数组就是HashMap主干。 HashMap 数组每一个元素初始值都是 Null。 ...
  • 区间调度问题

    2019-09-27 14:53:00
    1. 相关定义 在数学里,区间通常是指这样一... 在程序世界,区间的概念数学里没有区别,但是往往有具体含义,例如时间区间,工资区间或者音乐中音符开始结束区间等,图一给出了一个时间区间的例子。区间有...
  • 分区 分区就是把一个数据表文件索引分散存储...LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合某个值来进行选择。 HASH分区:基于用户定义表达式返回值来进行选择分区,...
  • 符号集合近似法SAX

    2020-06-28 18:19:08
    一些时间序列分类问题可能涉及时间序列属性差异,这些属性被限制在特定区别时间区间内,即所谓局部特征。 1. SAX算法1 笼统地理解,SAX((Symbolic Aggregate approXimation,符号集合近似)算法是将时间...
  • 一 目录 不折腾前端,咸鱼有什么区别目录一 目录二 题目三 解题思路四 统计分析五 解题套路二 题目 给出一个区间的集合,请合并所有重叠的区间。 示例1: 输入:[[1,3]...
  • 2.描述HashsetHashMap的区别。3.年级的集合使用Map的嵌套实现。 10班,每个班50人。4.编程实现文本文件的复制。合理设计程序,得到缓冲区的大小的高效区间。 提示缓冲区设置1k开始,不超过10M。==================...
  • 2.描述HashsetHashMap的区别。3.年级的集合使用Map的嵌套实现。 10班,每个班50人。4.编程实现文本文件的复制。合理设计程序,得到缓冲区的大小的高效区间。 提示缓冲区设置1k开始,不超过10M。------------------...
  • MySQL分区分表

    2019-05-22 14:52:26
    分区 分区就是把一个数据表文件索引分散存储在...LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合某个值来进行选择。 HASH分区:基于用户定义表达式返回值来进行选择分区...
  • mysql分区分表

    2018-09-29 09:31:27
    mysql分区分表 分区 分区就是把一个数据表文件索引分散存储在不同物理...LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合某个值来进行选择。 HASH分区:基于用户定...

空空如也

空空如也

1 2 3 4 5
收藏数 81
精华内容 32
关键字:

区间和集合的区别