java的集合

集合

1 课程名称:集合

2 知识点概述

2.1、上次课程

2.2、作业讲解

2.3、本次预备讲解的知识点

1、  Collection接口、List接口、Set接口的作用及关系

2、  Map接口的作用

3、  集合的四种输出方式及使用区别

4、  集合的常用操作子类

3、具体内容

3.1、认识类集

在编程时,常常需要集中存放多个数据,当然我们可以使用数组来保存多个对象。但数组的长度不可变化,一旦在初始化数组是指定了数组的长度,则这个数组长度是不可变的,如果需要保存个数变化的数据,数组就有点无能为力了;而数组也无法保存具有映射关系的数据,如成绩表:语文--79, 数学—80,这种数据看上去像两个数组,但这两个数组直接的元素具有一定的关联关系。

       为了保存数量不确定的数据,以及保存具有映射关系的数据(也称为关联数组),java提供了集合类,集合类主要负责保存,盛放其他数据,因此集合类也被称为容器类。所有的集合类都位于java.util包下。

       Java的集合类主要由以下接口派生而出:

1.    Collection系类接口——单值操作接口

a)    Collection接口派生出Set、Queue、List三个子接口

2、 Map系类接口——对值操作接口,由key-value对组成

常用实现类为:HashMap、properties、SortedMap

      此外还经常用到如下接口:

1、SortedSet、SortedMap排序的操作接口

2、Interator、ListInterator输出集合中元素的接口

 

结构如图:

 

三种常用集合特点

|- Set集合无序不能重复

|- List集合有序可重复

|- Map集合Key不可重复、value可重复

3.2、Collection接口    

3.2.1、collection接口的定义

Colletion接口的定义

public interface Collection<E>
extends Iterable<E>

在JDK1.5之后,collection接口使用了泛型的定义,在操作时必须指定具体的操作类型,这样可以保证类操作的安全性,避免发生ClassCastException异常

Collection接口是单值存放的最大父接口,可以向其中保存多个单值(单个对象)数据,Collection接口里定义了如下操作集合元素的方法:(详见API)

No

方法

类型

描述

1

public boolean add(E e)

普通

向集合中添加元素

2

public boolean addAll(Collection<? extends E> c)

普通

向集合中添加一组数据,泛型指定了操作上限

3

public void clear()

普通

清空所有集合中的所有元素

4

public boolean contains(Object o)

普通

判断是否有指定的内容,查找

5

public boolean containsAll(Collection<?> c)

普通

查找一组数据是否存在

6

public boolean equals(Object o)

普通

比较对象是否相等

7

public int hashCode()

普通

返回hash码

8

public boolean isEmpty()

普通

判断集合是否为空

9

public Iterator<E> iterator()

普通

为interator接口实例化,迭代输出

10

public boolean remove(Object o)

普通

从集合中删除指定的对象

12

public boolean removeAll(Collection<?> c)

普通

从集合中删除一组对象

13

public boolean retainAll(Collection<?> c)

普通

从集合中保留指定的集合

14

public int size()

普通

获取集合中元素的个数

15

public Object[] toArray()

普通

取得集合中全部的元素,以数组的形式返回

16

public <T> T[] toArray(T[] a)

普通

返回包含此 collection 中所有元素的数组,可指定返回数组的类型

在一般开发中,往往很少直接直接使用Collection接口进行开发,基本上都是是其使用子接口,子接口主要有List、set、Query和StortedSet

3.2.2、collection子接口的定义

       Collection接口虽然是集合的最大接口,但如果直接使用Collection接口进行操作,则表示操作意义不明确,所以在java开发中不提倡直接使用collection接口,主要子接口介绍如下:

       |- List:可以存放重复的内容

|- Set:不能存放重复内容

|- Queue:队列接口

|- SortedSet:可以对集合中的数据进行排序

3.3、List接口

       ListCollection的子接口其中可以保存各个重复的内容,此接口定义如下:

public interface List<E>
extends Collection<E>

       但与Collection不同的是,在List接口中大量的扩充了Collection接口,拥有了比Collection接口中更多的方法定义,其中有些方法还比较常用。

List对Collection接口的扩展方法如下:详见API

No

方法

类型

描述

1

public add(int index, E element)

普通

将元素element放入在List集合的index处

2

public addAll(int index, Collection<? extends E> c

普通

将集合c所包含的所有元素都放入在List集合的index出,泛型指定了操作上限

3

public E get(int index)

普通

返回集合index索引处的元素

4

public int indexOf(Object o)

普通

返回对象o在集合中第一次出现的位置索引,如果此集合不包含该元素,则返回 -1。

5

public Boolean containsAll(Collection<?> c)

普通

查找集合C中的数据是否存在指定集合中存在

6

public int lastIndexOf(Object o)

普通

返回此集合中最后出现的指定元素的索引;如果集合不包含此元素,则返回 -1

7

public ListIterator<E> listIterator()

普通

返回listIterator实例

8

public ListIterator<E> listIterator(int index)

普通

返回从指定位置开始的listiterator实例

9

public E remove(int index)

普通

从集合中删除指定位置的元素

10

public E set(int index,E element)

普通

用指定元素替换列表中指定位置的元素

12

public List<E> subList(int fromIndex, int toIndex)

普通

返回集合中指定的 下标fromIndex(包括 )和 toIndex(不包括)之间的子集合,

如果使用想要使用此接口,则需要通过其子类进行实例化

3.3.1、List接口的常用子类

1、子类ArrayList

ArrayList是List的子类,可直接通过对象的多态性为List接口实例化,此类的定义如下:

public class ArrayList<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable

       可看出ArrayList继承了AbstractList,AbstractList类的定义如下:

public abstract class AbstractList<E>
extends AbstractCollection<E>
implements List<E>

       此接口实现了List接口,所以可以直接使用ArrayList为List接口实例化

 

示例代码:(向集合中添加元素)

ArrayList<Integer> obj = new ArrayList<Integer>();

              obj.add(23);

              obj.add(33);

              obj.add(44);

              obj.add(55);

说明:

从程序运行中可以发现,使用List中的add(int index,E element)方法可以在集合中指定位置增加元素,而其他两个add()方法只能在集合的最后进行内容的追加

 

示例代码:(删除元素)

array.remove(new Integer(33));

说明:

可同下标和对象的方式直接对集合进行删除

 

示例代码:(输出List中的内容)

Iterator<Integer> iter = array.iterator();

             

       while (iter.hasNext())

                     System.out.println(iter.next());

说明:

List集合增加到的顺序就是输出后的顺序,本身顺序不会改变

 

实例代码:(将集合变为对象数组)

Object[] intarr;

       intarr = array.toArray()

 

示例代码:(集合中的其他操作)

for (Object obj: intarr)

                     System.out.println(obj);

       }

 

2、LinkedList子类、Queue接口

       LinkedList表示链表的操作类,即java中已经为开发者提供好了一个链表程序,开发者直接使用即可,无需重复开发,LinkedList类的定义如下:

 

public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, Serializable

此类实现了List接口,但同时也实现了Queue接口。Queue表示的是队列操作接口,采用FIFO(先进先出)的操作方法,就好像一队人排队那样,队列中有对头和队尾,队头永远指向新加入的对象,Queue是Collection的子接口,其定义如下:

public interface Queue<E>
extends Collection<E>

Queue接口定义的方法如下:详见API

NO

方法

 

1

add(E e)

 

2

element()

获取但不移除此列表的头(第一个元素)。

3

offer(E e)

 

4

peek()

获取但不移除此列表的头(第一个元素)。

5

poll()

获取并移除此列表的头(第一个元素)

6

remove()

 

在LinkedList类中除了实现以上的方法外,还提供了如下方法:详见API

NO

方法

 

1

addFirst(E e)

将指定元素插入此列表的开头。

2

addLast(E e)

将指定元素添加到此列表的结尾。

3

offer(E e)

 

 

removeFirst()

 

 

removeLast()

 

 

示例代码:(链表的开头和结尾增加数据)

LinkedList<position> link = new LinkedList<position>();

              position p1 = new position(1,1);

              position p2 = new position(2,2);

              position p3 = new position(3,3);

              position p4 = new position(4,4);

              link.add(p3);

              link.add(p4);

              link.add(p1);

              link.add(p2);

              System.out.println(link);

              link.addFirst(new position(2,2));

              link.addLast(p4);

 

示例代码 :(找到链表头)

       System.out.println(link.pollFirst());

 

示例代码:(以先进先出的方式取出全部的数据)

System.out.println(link);

 

3.4、Set接口

Set接口也是Collection的子接口但是与CollectionList接口不同的是,Set接口中不能加入重复的元素。Set接口定义如下:

public interface Set<E>
extends Collection<E>

从定义可以发现set接口和List接口没有头太大差异,但是Set接口的主要方法和Collection一致的,也就是说set接口并没有对Collection接口进行扩充,只是比Collection接口的要求更加严格了,不能增加重复元素

Set接口的实例不能像List接口那样进行双向输出,因为此接口没有提供像list接口定义的get(int index)方法

 

3.4.1、Set接口的常用子类

1、散列的存放:HashSet

HashSet是set接口的一个子类,主要的特点是:里面不能存放重复元素,而且采用散列的存储方式,所以没有顺序

 

实例代码:(HashSet类)

HashSet<Integer> hash = new  HashSet<Integer>();

说明:

       从程序运行结果可以看出,重复元素只能增加一次,而且程序运行时向集合加入元素的顺序并不是集合中保存的顺序,证明HashSet类中的元素是无序排列的

2、有序存放:       TreeSet

       如果想对输入的数据进行排序,则要使用TreeSet子类,TreeSet类定义如下:

public class TreeSet<E>
extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, Serializable

       TreeSet继承了AbstractSet类,此类定义如下:

public abstract class AbstractSet<E>
extends AbstractCollection<E>
implements Set<E>

 

示例代码:(验证TreeSet)

       TreeSet<Integer>  tree = new TreeSet<Integer>();

              tree.add(1);

              tree.add(34);

              tree.add(56);

              tree.add(667);

              System.out.println(tree);

              tree.clear();

              System.out.println(tree);

              System.out.println(tree.contains(34));

              System.out.println(tree.first());

              System.out.println(tree.floor(2));

            System.out.println(tree.hashCode());

              System.out.println(tree.higher(70));

           System.out.println(tree.last());

              System.out.println(tree.remove(34));

              System.out.println(tree);

 

说明:

       程序在向集合中添加数据时是没有顺序的,但输出之后是有序的,所以TreeSet是可以排序的子类

 

3、关于TreeSet排序的说明

       既然TressSet本身是可以排序的,那么现在定义一个自己的类,是否也可要进行排序操作呢?

示例代码:(自定义类排序)

TreeSet<position>  tree = new TreeSet<position>();

                     tree.add(p4);

                     tree.add(p3);

                     tree.add(p2);

                     tree.add(p1);

                     tree.add(new position(1,1));

                     System.out.println(tree);

                     System.out.println(tree.contains(p2));

                     System.out.println(tree.first());

                     System.out.println(tree.lower(p3));

                     System.out.println(tree.pollFirst());

                     System.out.println(tree);

                     System.out.println(tree.pollLast());

                     System.out.println(tree);

              System.out.println(tree.toArray());

说明:

       出现类型转换异常,因为TreeSet中的元素是有序存放的,所以对于一个对象必须指定好其排列规则,且TressSet中的每个对象所在的类都必须实现Comparable接口才可正常是使用

 

示例代码:(指定排列规则)

class position implements Comparable<position>{

       int x;

       int y;

       position(int x, int y){

              this.x = x;

              this.y = y;

       }

       public String toString(){

              return "x="+x+"  y="+y;

       }

       public int compareTo(position  obj){

              if(obj.x >x)                   

              return 1;

              else if(obj.x < x)

                     return -1;

              else{

                     if(obj.y> y)

                            return 1;

                     else if(obj.y < y)

                            return -1;

                     else

                            return 0 ;

              }

       }

}

说明:

       从程序运行结果中发现,重复的“吕子乔”没有加入,但年龄重复的“美嘉“没有添加到集合中,这是由于采用了比较器造成的,因为比较器操作时如果某个属性没有进行比较的指定,则也会认为是同一个对象,所以此时应该在Person类中compareTo方法中增加姓名比较

 

示例代码:(修改Person比较器)

 

说明:

       此时,运行结果中出现了年龄重复的“美嘉”,而且去掉了重复内容,但此时重复内容去掉,并不是真正意义上的去掉重复元素。因为此时靠的是Comparable完成的,而如果换成HashSet则也会出现重复内容,所以要想真正的去掉重复元素,则必须深入研究Object类

 

4、关于重复元素的说明

       观察以下代码:

说明:

       从程序运行结果可以发现“吕子乔”元素重复了,也就是说,此时的程序并没有像Set接口规定的那样是不允许有重复元素的,而如果此时想要去掉重复元素,则必须首先进行对象是否重复的判断,而要想进行这样的判断则一个类就必须重写Object类中的equals方法,才能完成对象是否相等的判断,但是只重写equals()方法是不够的,还需要重写hashCode()方法,此方法表示一个哈希编码,可以简单的理解为表示一个对象的编码。一般的哈希吗是通过公式进行计算的,可以将类中的全部属性进行适当的计算,以获取不能重复的哈希码

说明:

       集合中的重复元素消失了,就是因为equals()和hashCode()共同作用的结果

 

3.5、SortedSet接口  

       从TreeSet类的定义中可以发现,TreeSet类中实现了SortedSet接口,此接口主要用于排序操作,即实现此接口的子类都属于排序的子类,SortedSet接口定义如下:

public interface SortedSet<E>
extends Set<E>

       此接口也继承了Set接口,此接口中定义了如下方法:

NO

方法

 

1

comparator()

 

2

first()

 

3

headSet(E toElement)

 

4

last()

 

5

subSet(E fromElement, E toElement)

 

6

tailSet(E fromElement)

 

 

示例代码:(验证SortedSet接口)

 

 

3.6、集合的输出

       之前我们知道,如果输出Collection,set集合中的内容,可以将其转换为数组输出,而是用list则可直接通过get()方法输出,但这些不是集合的标准输出方式,在类集合中提供了如下4中常见的输出方式:

1、 Iterator:迭代输出,是用最多的方式

2、 ListIterator:是Iterator的子接口,功能与Iterator类似

3、 Enumeration:是一个旧接口,功能与Iterator类似

4、 foreach:JDK1.5以后的新功能,可以输出输出或集合

3.6.1、Iterator迭代输出

1、Iterator接口

       在使用集合输出时必须形成一个思路,“只要碰到了集合输出的操作,就一定使用Iterator接口”,因为这是一个最为标准的做法

       Iterator是专门迭代输出接口,所谓迭代输出就是将元素一个一个进行判断,判断其是否有内容,如果有内容则把内容取出,Iterator接口的定义如下:

public interface Iterator<E>

       Iterator接口在使用时也要使用泛型,当然此处的泛型最好与集合中的泛型类型一致,此此接口定义的方法如下:(详见API)

NO

方法

说明

1

hasNext()

 

2

next()

 

3

remove()

 

 

2、Iterator接口的相关操作

       Iterator接口,可以直接使用Collection接口中定义的Iterator()方法为其实例化,既然Collecting接口中存在了此方法,则List和Set接口中也一定存在此方法,所有也可以通用使用Iterator接口输出。

 

示例代码:(输出Collection中的全部内容)

 

说明:

       集合类的标准输出形式,(重点掌握),将集合中的元素一个一个输出

 

示例代码:(使用Iterator删除指定内容)

 

 

示例代码:(迭代输出时删除元素的注意点)

       正常情况下,一个集合要把内容交给iterator输出,但集合操作也存在一个remove()方法,如果在使用iterator输出集合时自己调用了删除的方法,则会出现运行错误。

示例代码:(不正确的删除方法)

 

说明:

       从程序运行结果中可以发现,内容却是被删除了,但迭代输出在内容被删除之后就终止了。因为集合本身内容被破换掉,所有迭代输出将出现错误,会停止输出。

 

3.6.2、ListIterator双向迭代输出

1、ListIterator接口简介

       Iterator接口的主要功能是由前向后单向输出,而此时如果实现由后向前或是由前向后的双向输出,则必须使用Iterator的子接口 ---- ListIterator,定义如下:

public interface ListIterator<E>
extends Iterator<E>

      

此接口比Iterator接口中定义了更多的方法,具体如下:(详见API)

 

 

 

 

NO

方法

说明

1

add(E e)

 

2

hasNext()

 

3

hasPrevious()

 

4

next()

 

5

nextIndex()

 

6

previous()

 

7

previousIndex()

 

8

remove()

 

9

set(E e)

 

 

与Iterator接口不同的是,ListIterator接口只能通过List接口实例化,即只能输出list接口的内容,在List接口中定义可以为ListIterator接口实例化的方法ListIterator().

 

2、ListIterator接口的相关操作

示例代码:(进行双向迭代)

 

说明:

1、 此输出方式只有list接口才可以做到

2、 如果想完成由后向前的输出,则一定要先进行由前向后的输出

示例代码:(增加即替换元素)

 

说明:

       虽然add()或set()方法可以增加和替换集合中的元素,但在开发中不建议使用。

3.6.3、java的新支持:foreach

       foreach除了可以完成数组输出,对于集合同样支持,语法如下:

for(类 对象:集合)

{

 //集合操作

}

 

示例代码:(使用foreach输出)

for (Object obj: intarr)

                     System.out.println(obj);

      

说明:

虽然foreach使用较简单,在实际的开发中iterator还是较多

3.7、Map接口

3.7.1、Map接口简介

Collection、List、set接口都是单值的操作,即每次只能操作一个对象,而map与他们不同的是,每次操作是一对对象,即二元偶对象,map中的每个元素都使用key—value对的形式存储在集合中。Map接口的定义如下:

public interface Map<K,V>

map也使用了泛型,必须同时设置还key或value的类型,在map中每一对key—value都表示一个值,map接口提供的如下方法:(详见API)

NO

方法

 

 

clear()

 

 

containsKey(Object key)

 

 

containsValue(Object value)

 

 

entrySet()

 

 

equals(Object o)

 

 

get(Object key)

 

 

hashCode()

 

 

isEmpty()

 

 

keySet()

 

 

put(K key, V value)

 

 

putAll(Map<? extends K,? extends V> m)

 

 

remove(Object key)

 

 

size()

 

 

values()

 

 

3.7.2、Map.Entry接口简介

       Map.Entry是Map内部定义的一个接口,专门用来保存key---value的内容,Map.Entry定义如下:

public static interface Map.Entry<K,V>

Map.Entry是使用static关键字声明的内部接口,此接口可以通过“外部类.内部类”的形式直接调用,本接口定义方法如下:

NO

方法

说明

1

equals(Object o)

 

2

getKey()

 

3

getValue()

 

4

hashCode()

 

5

setValue(V value)

 

我们可以把Map理解成一个特殊的Set,只是该set里包含的集合元素时Entry对象。

 

3.7.3、Map接口的常用子类

Map接口常用的子类如下:

1、 HashMap:无序存放,是新的操作类,key不允许重复

2、 Hashtable:无序存放,是旧的操作类,key不允许重复

3、 TreeMap:可以排序的map集合,按集合的key排序,key不允许重复

1、 新的子类:HashMap

HashMap本身是Map子类,直接使用此类为map接口实例化即可。Hashmap定义如下:

public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable

HashMap是AbstractMap的子类,abstractMap类的定义如下:

public abstract class AbstractMap<K,V>
extends Object
implements Map<K,V>

 

2、 相关操作实例

所有的操作都是以Map接口作为标准,且HashMap最为常见

 

实例代码:(向集合中增加或取出内容)

HashMap<String,Integer> hashmap  =new HashMap<String,Integer>();

                     hashmap.put("math", 100);

hashmap.put("chainese", 96);

                     hashmap.put("english", 80);

                     hashmap.put("java", 132);

 

示例代码:(判断指定内容是否存在)

System.out.println(hashmap.containsKey("java"));

 

示例代码:(输出全部key)

Collection<String> obj =hashmap.keySet();

                     System.out.println(obj);

 

示例代码:(输出全部value)

Collection<Integer> tmp = hashmap.values();

                     System.out.println(tmp);

 

 

3、 排序的子类:TreeMap

TreeMap的主要功能是按照Key排序

 

示例代码:(TreeMap的排序)

public static void main(String[] args) {

              TreeMap<position, Integer> treemap = new TreeMap<position,Integer>();

              treemap.put(new position(1,1),1);

              treemap.put(new position(2,2),2);

              treemap.put(new position(3,3),3);

              treemap.put(new position(4,4),4);

              treemap.put(new position(5,5),5);

              System.out.println(treemap);

              System.out.println(treemap.hashCode());

              System.out.println(treemap.get(new position(1,1)));

              System.out.println(treemap.lastEntry());

              System.out.println(treemap.remove(new position(3,3),3));

              System.out.println(treemap);

              System.out.println(treemap.size());

              System.out.println(treemap.keySet());

              System.out.println(treemap.values());

             

              System.out.println("+++++++++++++++++++++++++++++");

              Collection<Integer> val = treemap.values();

 

              Integer [] arr = new Integer [1];

              arr = val.toArray(arr);

              for(Integer a: arr){

                     System.out.println(a);

              }

                    

说明;

        此代码使用的是string类作为key,因为string类本身已经实现了Comparable接口,所以程序执行不会有任何问题,如使用自定义类作为key则必须实现comparable接口,否则将出现异常

 

3.7.4、Map接口的注意事项

1、注意事项:不能直接使用迭代直接输出map中的全部内容

        对于Map接口来说,本身不能直接使用迭代输出(Iterator,foreach)进行输出的,因为map中每个位置存放的是一对值(key---value),而Iterator中每次只能找到一个值。所如果非要使用迭代进行输出,则必须按如下步骤完成:

a)    将Map的实例通过entrySet()方法变为set接口对象

b)    通过set接口实例为Iterator实例化

c)     通过iterator迭代输出,每个内容都是Map.Entry对象

d)    通过Map.Entry进行key----value的分离

Map中的每对数据集都是通过Map.Entry保存的,所以如果要最终进行输出也应该使用Map.Entry完成,Map集合在实际开发中基本上作为查询应用的较多,全部输出内容的操作较少。

 

示例代码:(Iterator输出Map)

 

 

示例代码;(使用foreach输出Map)

for(Integer a: arr){

                     System.out.println(a);

              }

 

2、注意事项:使用非系统类所为key

       我们使用自定义的类Person替换Map集合中的value

 

说明:

       以上查找对象的方式是通过字符串匿名对象的方式查找的,从结果看,是能够查找到对应的内容。那么现在两个类型交换一下位置?即key用自定义类Person替换

说明:

       以上的程序和之前的结构差不多,只是使用了Person的匿名对象作为Key,将字符串的匿名对象做了value,唯一不同的是改变了之前的key和value的位置,但此时无法查到对应的内容,为什么一开始使用string可以,而现在使用Person对象不可以,为了研究这个问题,继续观察下面代码:

 

 

说明:

       根据Key能够找到value,但为什此时可以找到,而之前不可以。因为之前的操作对象是以Person匿名对象完成的,但现在进行查找操作时使用的并不是匿名对象,这样程序中设置和取得时都使用了Person的实例化对象,地址没有改变,所以可以找到。

       但是所有的程序不可能这样去完成查找功能,用户在真正操作时不可能明确的知道其中引用地址,都应该像String那样可以通过匿名对象找到对应的value,要实现这样的功能,就靠Object类中hashCode()和equeals()方法的帮助,以方便区分是否是同一个对象。

 

示例代码:(重写hashCode、equals方法)

public int hashCode(){

    return x*y;

  }

  public boolean equals(Object o){

    position obj = (position)o;

    if(obj.x == x && obj.y == y)

      return true;

    else

      return false;

  }

说明:

       如果要使用自定类作为Map中的key,则对象所在的类中一定要重写equals、hashCode方法;否则无法找到对应的value

 

3.8、SortedMap接口

       SortedMap接口是排序接口,只要是实现了此接口的子类,都属于排序的子类,TreeMap也是此接口的一个子类,SortedMap接口的定义如下:

public interface SortedMap<K,V>
extends Map<K,V>

 

SortedMap接口扩展了Map中的方法,常用如下:(详见API)

NO

方法

 

1

comparator()

 

2

entrySet()

 

3

firstKey()

 

 

headMap(K toKey)

 

 

keySet()

 

 

lastKey()

 

 

subMap(K fromKey, K toKey)

 

 

tailMap(K fromKey)

 

 

values()

 

 

 

说明;

       以上使用了Map接口中没有的方法,但如果操作以上的方法,则对象所在的类必须实现Comparable接口。

 

4 总结

5 预习任务

6 作业

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值