黑马程序员:集合框架

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

概述:

集合的由来:还是数据的存储需要容器的原因。原有的容器有数组跟StringBuilder/StringBuffer

数组的最大缺点在于长度不可变,而且作为容器其没有自己的操作方法,只有一个属性length

另外一个容器StringBuilder/StringBuffer是用来存储字符串的,只有当你在最终想要得到字符串的时候,用这个容器才比较合适,而且进去之后,无论进去多少,出来都只有一个整体,分不清第几个。其局限性也很大。

而集合框架好像就是为了解决前面两个容器的问题才出现的。集合框架体系中包含多个不同的容器,常用的容器ArrayList,LinkedList,HashSet,HashMap都是长度可变的,而且都有自己的方法,操作方便。此外,其中能存储多种数据!只要能转为对象的都可以存储。包括基本数据类型——可以转为对应的包装类,字符串,自定义对象等等多种数据类型。有的还能存储映射关系!

体系:

集合框架大体上可以分为单列集合Collection和双列集合Map

单列集合Collection<E>

单列集合CollectionCollection层次结构之中的根接口,里面定义了这个结构之中的共性方法。

 boolean

add(E e)  确保此 collection 包含指定的元素(可选操作)。

 boolean

addAll(Collection<? extends E> c)将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。

 void

clear()     移除此 collection 中的所有元素(可选操作)。

 boolean

contains(Object o) 如果此 collection 包含指定的元素,则返回 true

 boolean

containsAll(Collection<?> c) 如果此 collection 包含指定 collection 中的所有元素,则返回 true

 boolean

equals(Object o)比较此 collection 与指定对象是否相等。

 int

hashCode() 返回此 collection 的哈希码值。

 Iterator<E>

iterator()返回在此 collection 的元素上进行迭代的迭代器。

 boolean

remove(Object o)从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。

 boolean

removeAll(Collection<?> c) 移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。

 boolean

retainAll(Collection<?> c) 仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。

 int

size() 返回此 collection 中的元素数。

 Object[]

toArray()  返回包含此 collection 中所有元素的数组。

<T> T[]

toArray(T[] a)  返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。

总的来说可以分为增(add)删(removeclear)查(contains)这几种操作,还有子类中要用的方法:hashCode()equals()方法。

迭代器Iterator

需要特殊说明的是iterator()方法,Iterator代表迭代器,是该层次结构通用的遍历元素的方法。该层次结构并不是所有的类都能如数组一样用下表来操作元素。所以需要一个特殊的方法——迭代器!该迭代器通过实现Iterable<E>接口取得。

迭代器实际上是Collection之中的一个内部类,而iterator()方法就是获取这个内部类的对象。该内部类之中定义了一些获取该集合之中数据的方法,所以得到这个内部类的对象之后调用其方法就可以获取该集合的元素了。

迭代器之中实际包含了三个方法,单常用的是前面两个:

 boolean

hasNext()          如果仍有元素可以迭代,则返回 true

 E

next()          返回迭代的下一个元素。

 void

remove()          从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。

迭代器使用的例子:

for(Iterator<E> it=collection.iterator();it.hasNext();)//获取迭代器,判断是否有下一个元素

{

E ele=it.next();//如果有,获取该元素

}

Collection的子接口:ListSet

List<E>:有序的collection,序列,允许重复元素(存入取出顺序一致)

这个子接口的最大特点是像数组一样有索引,所以此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。正由于其索引的存在,它区别元素的时候并不用靠元素本身来区分,所以可以存储相同的元素。这点与另外一个子接口Set不同。

List接口作为Collection的子接口,除了继承而来的iterator、add、remove、equals 和 hashCode 方法之外,还包含自己的独特方法——与索引相关的操作。

 void

add(int index, E element)   在列表的指定位置插入指定元素(可选操作)。

 boolean

addAll(int index, Collection<? extends E> c)  将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。

 E

get(int index)          返回列表中指定位置的元素。

 int

indexOf(Object o)          返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1

 int

lastIndexOf(Object o)          返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1

 ListIterator<E>

listIterator()          返回此列表元素的列表迭代器(按适当顺序)。

 ListIterator<E>

listIterator(int index)          返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。

 E

remove(int index)          移除列表中指定位置的元素(可选操作)。

 E

set(int index, E element)          用指定元素替换列表中指定位置的元素(可选操作)。

 List<E>

subList(int fromIndex, int toIndex)          返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。

可以看出,List有自己获取元素的方法get(int index),还有自己的迭代器ListIterator<E>

get(index)方法可以让我们像遍历数组一样来对List序列进行遍历,不过列表元素上迭代通常优于用索引遍历列表。

List自己特殊的迭代器ListIterator,除了允许 Iterator 接口提供的正常操作外,该迭代器还允许元素插入和替换,以及双向访问。还提供了一个方法来获取从列表中指定位置开始的列表迭代器。

 boolean

hasPrevious()          如果以逆向遍历列表,列表迭代器有多个元素,则返回 true

 int

nextIndex()          返回对 next 的后续调用所返回元素的索引。

 E

previous()          返回列表中的前一个元素。

 int

previousIndex()          返回对 previous 的后续调用所返回元素的索引。

 void

set(E e)          用指定元素替换 next 或 previous 返回的最后一个元素(可选操作)。


注意:尽管列表允许把自身作为元素包含在内,但建议要特别小心:在这样的列表上,equals 和 hashCode 方法不再是定义良好的,不一定是符合需要的。

List之中包含ArrayListLinkedList这两个常用的实现类,另一个Vector较少用。

Set<E>:不包含重复的collection,不保证有序

Set<E>判断元素是否重复依赖于equals()方法,最多包含一个null元素!

当要添加一个元素到该容器之中的时候,会先调用该元素的equals方法来判断是否已经有了相同的元素,如果返回true,则说明已经有相同元素,添加失败;如果返回false,说明没有该元素,添加成功。

Set之中的常用实现类有HashSetTreeSet

双列集合Map<K,V>

Map<K,V>集合:用来存储将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。

Map接口自己没有迭代器,也没有其他直接获取其元素的方法。所以要查看其元素,只能先转化成Collection单列集合,然后通过Collection的迭代器来查看其中的元素。Map提供三种collection视图,允许以键集、值集或键-值映射关系集的形式查看某个映射的内容。

Map之中的方法有:

 void

clear()          从此映射中移除所有映射关系(可选操作)。

 boolean

containsKey(Object key)          如果此映射包含指定键的映射关系,则返回 true

 boolean

containsValue(Object value)          如果此映射将一个或多个键映射到指定值,则返回 true

 Set<Map.Entry<K,V>>

entrySet()          返回此映射中包含的映射关系的 Set 视图。

 boolean

equals(Object o)          比较指定的对象与此映射是否相等。

 V

get(Object key)      返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null

 int

hashCode()          返回此映射的哈希码值。

 boolean

isEmpty()          如果此映射未包含键-值映射关系,则返回 true

 Set<K>

keySet()          返回此映射中包含的键的 Set 视图。

 V

put(K key, V value)          将指定的值与此映射中的指定键关联(可选操作)。

 void

putAll(Map<? extends K,? extends V> m)从指定映射中将所有映射关系复制到此映射中(可选操作)。

 V

remove(Object key)          如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。

 int

size()          返回此映射中的键-值映射关系数。

 Collection<V>

values()          返回此映射中包含的值的 Collection 视图。


Map之中的增操作是通过putputAll来实现的,一次添加的是键值对。

查看其元素的三种方式:

1keySet()方法得到对应的键集,然后调用其迭代器,来查看所有的键,如果想要查看键对应的值,可以使用get()方法
2entrySet()方法得到键值映射关系集,然后调用其迭代器,来查看每一个键值映射关系,如果想要查看具体的键和值,可以调用键值映射关系这个对象的方法:getKey()getValue()

3values()方法得到值集

Map的常用实现类HashMapTreeMap

Collection单列集合之中的类:

List的体系结构

|--Vector:低层数据结构是一个数组,而且数组可以增长。

是同步的,多线程安全

——效率非常低

枚举是Vector元素的取出方式,也是内部类

Enumeration的功能与Iterator接口的功能是重复的,被迭代器取代了,因为名 字太长

|--ArrayList底层数据结构也是可变长度的数组,是不同步的。

特点:增删速度慢,但是查询快(数组空间连续)

StringBufferStringBuilder的区别。单线程多线程都不用Vector,多线程中用改进的ArrayList

|--LinkedList底层数据结构是链表数据结构,是不同步的。

特点:元素的增删很快,但是查询慢(链表的存储空间不连续)

数组可变长度的原理:

存储元素时,超出数组角标,则建立新的数组,把原来数组存储到新数组中,再把新的元素添加进去。

LinkedList的特有方法:由于其数据结构决定了其增删的便捷,所以其还有自己特有的头尾增删方法

 void

addFirst(E e)          将指定元素插入此列表的开头。

 void

addLast(E e)          将指定元素添加到此列表的结尾。

 Iterator<E>

descendingIterator()          返回以逆向顺序在此双端队列的元素上进行迭代的迭代器。

 E

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

 E

getFirst()          返回此列表的第一个元素。

 E

getLast()          返回此列表的最后一个元素。

 ListIterator<E>

listIterator(int index)返回此列表中的元素的列表迭代器(按适当顺序),从列表中指定位置开始。

 boolean

offer(E e)          将指定元素添加到此列表的末尾(最后一个元素)。

 boolean

offerFirst(E e)          在此列表的开头插入指定的元素。

 boolean

offerLast(E e)          在此列表末尾插入指定的元素。

 E

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

 E

peekFirst()          获取但不移除此列表的第一个元素;如果此列表为空,则返回 null

 E

peekLast()          获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null

 E

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

 E

pollFirst()          获取并移除此列表的第一个元素;如果此列表为空,则返回 null

 E

pollLast()          获取并移除此列表的最后一个元素;如果此列表为空,则返回 null

 E

pop()          从此列表所表示的堆栈处弹出一个元素。

 void

push(E e)          将元素推入此列表所表示的堆栈。

 E

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

 E

remove(int index)          移除此列表中指定位置处的元素。

 boolean

remove(Object o)          从此列表中移除首次出现的指定元素(如果存在)。

 E

removeFirst()          移除并返回此列表的第一个元素。

 boolean

removeFirstOccurrence(Object o)从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表时)。

 E

removeLast()          移除并返回此列表的最后一个元素。

 boolean

removeLastOccurrence(Object o)从此列表中移除最后一次出现的指定元素(从头部到尾部遍历列表时)。

Set的体系结构

|--HashSet:底层数据结构是哈希表,是不同步的。无序,高效;

HashSet集合保证元素唯一性:通过元素的hashCode方法,和equals方法完成的。

当元素的hashCode值相同时,才继续判断元素的equals是否为true。

如果为true,那么视为相同元素,不存。如果为false,那么存储。

如果hashCode值不同,那么不判断equals,从而提高对象比较的速度。

      |--LinkedHashSet:有序,hashset的子类。

|--TreeSet:底层的数据结构就是二叉树,不同步,对Set集合中的元素的进行指定顺序的排序。

哈希表的原理:

1,对对象元素中的关键字(对象中的特有数据),进行哈希算法的运算,并得出一个具体的算法值,这个值称为哈希值。

2,哈希值就是这个元素的位置。

3,如果哈希值出现冲突,再次判断这个关键字对应的对象是否相同。如果对象相同,就不存储,因为元素重复。如果对象不同,就存储

4,存储哈希值的结构,我们称为哈希表。

5,既然哈希表是根据哈希值存储的,为了提高效率,最好保证对象的关键字是唯一的。

这样可以尽量少的判断关键字对应的对象是否相同,提高了哈希表的操作效率。

对于ArrayList集合,判断元素是否存在,或者删元素底层依据都是equals方法。

对于HashSet集合,判断元素是否存在,或者删除元素,底层依据的是hashCode方法和equals方法。

元素要在哈希表结构的容器中存储,必须具备hashCodeequals方法

Object中已经提供了这两个方法。但是其hashCode调用的是本地WindowshashCode方法,不一定符合需要。应该根据对象的自身特点,覆盖hashCode方法,建立自己的hashCode方法。

TreeSet:

用于对Set集合进行元素的指定顺序排序,排序需要依据元素自身具备的比较性。

如果元素不具备比较性,在运行时会发生ClassCastException异常。

所以需要元素实现Comparable接口,强制让元素具备比较性,复写compareTo方法。

依据compareTo方法的返回值,确定元素在TreeSet数据结构中的位置。

TreeSet方法保证元素唯一性的方式:就是参考比较方法的结果是否为0,如果return 0,视为两个对象重复,不存。

注意:在进行比较时,如果判断元素不唯一,比如,同姓名,同年龄,才视为同一个人。

在判断时,需要分主要条件和次要条件,当主要条件相同时,再判断次要条件,按照次要条件排序。

TreeSet集合排序有两种方式,Comparable和Comparator区别:

1:让元素自身具备比较性,需要元素对象实现Comparable接口,覆盖compareTo方法。

2:让集合自身具备比较性,需要定义一个实现了Comparator接口的比较器,并覆盖compare方法,并将该类对象作为实际参数传递给TreeSet集合的构造函数。

第二种方式较为灵活。

Collection集合的子类对象的阅读技巧:

具体的容器是什么结构?是否同步?

通过名称就可以获得。容器的前缀名是数据结构的名称,后缀名是所属体系的名字

凡是后缀名是体系名的集合,都是不同步的

ArrayList:数据结构是数组,所属List体系

看到数组就想到索引,就是查询速度快

LinkedList:数据结构是链表,所属List体系

增删速度快,add,get,remove的first,last头尾操作

HashSet:数据结构是哈希表,所属Set体系

看到哈希就有对元素进行hashCode和equals方法的复写

TreeSet:数据结构是二叉树,所属Set体系

看到就想到排序,就要想到两个接口Comparator,Comparable!

Map双列集合之中的类:

Map的体系结构:

|----Hashtable:数据结构是哈希表,同步的。不允许null作为键和值

|----HashMap:哈希表,不同步。允许null作为键和值,效率比Hashtable高,替代了Hashtable

|----TreeMap:数据结构二叉树,不同步的,可以对map中的键进行指定顺序的排序,默认是字典顺序。默认不行上比较器

在分析问题时,如果其中出现了映射关系,就要首先想到map集合进行存储

Map集合就是对应关系表

如果映射关系的数量是固定的,而且其中的对应关系的一方是有序的编号(索引),这时候可以使用数组进行存储。

其它:

泛型技术:

把运行时期的错误,放到编译时期,编译通过,则这种问题不会出现在运行时期

把类型转换异常这个运行异常提前到编译异常,用户输错数据,编译出错,连.class文件都产生不了

泛型由来:

1把运行时期的ClassCastException提前到编译时期,变成了编译失败

2泛型的出现避免了类型强制转换的麻烦

3,泛型技术是用在编译时期的技术

4,泛型的出现提高了类型的安全性

用户的问题由开发人员解决,消灭在开发时期

泛型:JDK1.5推出的一个安全机制

————java的升级方向,提高效率,简化书写,提高安全(把运行问题提前)

泛型的表现形式:用<>

当类型不确定的时候,定义变量<E>E是一个参数,用来接收数据类型,要用什么类型,传进来即可。

泛型的使用:

情况之一:类或者接口上定义了尖括号<>,就要使用泛型,把要用的具体类型传递进去即可

Object之中没有用泛型,所以继承并复写自Object的方法不能使用泛型,比如equals,只能使用强转。复写是一模一样!

之前使用的是Object来实现程序扩展性,使用的时候一定要强转,不强转就出错!但是强转是确定类型的强转,如果类型不确定,就会带来安全问题。

JDK1.5以后解决这个问题,要操作什么类型的对象可以由使用者来指定,我们只要在定义该工具类时,提供接受类型的参数就可以了。

class Tool{//泛型类的前身

private Object obj;

public static Object getObj(){

return obj;

}

public void setObj(Object obj){

this.obj=obj;

}

}

class Tool<Q>{//自定义泛型类

private Q obj;

public static Q getObj(){

return obj;

}

public void setObj(Q obj){

this.obj=obj;

}

}

什么时候使用自定义的泛型类呢?

当类中操作的数据类型不确定的时候就使用泛型类!

方法泛型/泛型方法:当方法操作的数据类型不确定的时候,定义泛型方法

public <Q> void show(Q t){

System.out.println("show:"+t);

}

静态方法上如果需要定义泛型,泛型必须定义在方法上!

public static <Y> void show(Y t){

System.out.println("static :"+t);

}

泛型接口:这个泛型可能不是由其实现类来明确的,可能是由其实现类的对象来明确的!

interface inter<T>{

abstract show(T t);

}

class imp <Q> implements Inter(){

public void show(Q q){};

}

当操作的类型不确定的时候,可以使用泛型,不需要定义具体类型参数进行操作时,使用通配符即可

通配符:?

public static void printCollection(Collection<?> a1){//?表示只能使用Object中的方法,但是它 //本身不代表任何类型,类型不确定

//Object是确定类型

Iterator<?> it=a1.iterator();

while(it.hasNext()){

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

}

}

泛型的存在就是为了解决安全问题的,尽量保持两边一致!两边不一致就有安全隐患!

通配符使用:boolean containsAll(Collection(Collection<?> c))

代表一个,?代表所有,

如果只要一部分——泛型的限定

Collection<? extends Person> coll

? extends E接受E类型及其子类,这样就可以使用E的特有方法了

——通常用于存储元素

? super E接受E类型及其父类

——当将元素取出时,可以使用本来类型,也可以使用本元素类型的父类型

List<? extends E <? super F>>list

Collections:

static <T>int binarySearch(List<? extends Comparable<? super T>> list, T key)
          使用二分搜索法搜索指定列表,以获得指定对象

Collections:它的出现给集合操作提供了更多的功能。这个类不需要创建对象,内部提供的都是静态方法。

静态方法:

Collections.sort(list);//list集合进行元素的自然顺序排序。

Collections.sort(list,new ComparatorByLen());//按指定的比较器方法排序。

class ComparatorByLen implements Comparator<String>{

public int compare(String s1,String s2){

int temp = s1.length()-s2.length();

return temp==0?s1.compareTo(s2):temp;

}

}

Collections.max(list); //返回list中字典顺序最大的元素。

int index = Collections.binarySearch(list,"zz");//二分查找,返回角标。

Collections.reverseOrder();//逆向反转排序。

Collections.shuffle(list);//随机对list中的元素进行位置的置换。

将非同步集合转成同步集合的方法:Collections中的  XXX synchronizedXXX(XXX);

List synchronizedList(list);

Map synchronizedMap(map);

原理:定义一个类,将集合所有的方法加同一把锁后返回。

Collection 和 Collections的区别

Collections是个java.util下的类,是针对集合类的一个工具类,提供一系列静态方法,实现对集合的查找、排序、替换、线程安全化(将非同步的集合转换成同步的)等操作。

Collection是个java.util下的接口,它是各种集合结构的父接口,继承于它的接口主要有Set和List,提供了关于集合的一些操作,如插入、删除、判断一个元素是否其成员、遍历等。

Arrays:

用于操作数组对象的工具类,里面都是静态方法。

asList方法:将数组转换成list集合。

String[] arr = {"abc","kk","qq"};

List<String> list = Arrays.asList(arr);//将arr数组转成list集合。

将数组转换成集合,有什么好处呢?用aslist方法,将数组变成集合;

可以通过list集合中的方法来操作数组中的元素:isEmpty()、contains、indexOf、set; 

注意(局限性):数组是固定长度,不可以使用集合对象增加或者删除等,会改变数组长度的功能方法。比如add、remove、clear。(会报不支持操作异常UnsupportedOperationException);

如果数组中存储的引用数据类型,直接作为集合的元素可以直接用集合方法操作。

如果数组中存储的是基本数据类型,asList会将数组实体作为集合元素存在。

集合变数组:用的是Collection接口中的方法:toArray();

如果给toArray传递的指定类型的数据长度小于了集合的size,那么toArray方法,会自定再创建一个该类型的数据,长度为集合的size。

如果传递的指定的类型的数组的长度大于了集合的size,那么toArray方法,就不会创建新数组,直接使用该数组即可,并将集合中的元素存储到数组中,其他为存储元素的位置默认值null。

所以,在传递指定类型数组时,最好的方式就是指定的长度和size相等的数组。

将集合变成数组后有什么好处?限定了对集合中的元素进行增删操作,只要获取这些元素即可。

Jdk5.0新特性:

Collection在jdk1.5以后,有了一个父接口Iterable,这个接口的出现的将iterator方法进行抽取,提高了扩展性。

--------------------------------------------------

增强for循环:foreach语句,foreach简化了迭代器。

格式:// 增强for循环括号里写两个参数,第一个是声明一个变量,第二个就是需要迭代的容器

for( 元素类型 变量名 : Collection集合 & 数组 ) {

}

高级for循环和传统for循环的区别:

高级for循环在使用时,必须要明确被遍历的目标。这个目标,可以是Collection集合或者数组,如果遍历Collection集合,在遍历过程中还需要对元素进行操作,比如删除,需要使用迭代器。

如果遍历数组,还需要对数组元素进行操作,建议用传统for循环因为可以定义角标通过角标操作元素。如果只为遍历获取,可以简化成高级for循环,它的出现为了简化书写。

高级for循环可以遍历map集合吗?不可以。但是可以将map转成set后再使用foreach语句。

1)、作用:对存储对象的容器进行迭代: 数组  collection   map

2)、增强for循环迭代数组:

String [] arr = {"a", "b", "c"};//数组的静态定义方式,只试用于数组首次定义的时候

for(String s : arr) {

System.out.println(s);

}

3)、单列集合 Collection:

List list = new ArrayList();

list.add("aaa");

// 增强for循环, 没有使用泛型的集合能不能使用增强for循环迭代?能

for(Object obj : list) {

String s = (String) obj;

System.out.println(s);

}

4)、双列集合 Map:

Map map = new HashMap();

map.put("a", "aaa");

// 传统方式:必须掌握这种方式

Set entrys = map.entrySet(); // 1.获得所有的键值对Entry对象

iter = entrys.iterator(); // 2.迭代出所有的entry

while(iter.hasNext()) {

Map.Entry entry = (Entry) iter.next();

String key = (String) entry.getKey(); // 分别获得key和value

String value = (String) entry.getValue();

System.out.println(key + "=" + value);

}

// 增强for循环迭代:原则上map集合是无法使用增强for循环来迭代的,因为增强for循环只能针对实现了Iterable接口的集合进行迭代;Iterable是jdk5中新定义的接口,就一个方法iterator方法,只有实现了Iterable接口的类,才能保证一定有iterator方法,java有这样的限定是因为增强for循环内部还是用迭代器实现的,而实际上,我们可以通过某种方式来使用增强for循环。

for(Object obj : map.entrySet()) {

Map.Entry entry = (Entry) obj;  // obj 依次表示Entry

System.out.println(entry.getKey() + "=" + entry.getValue());

}

5)、集合迭代注意问题:在迭代集合的过程中,不能对集合进行增删操作(会报并发访问异常);可以用迭代器的方法进行操作(子类listIterator:有增删的方法)。

6)、增强for循环注意问题:在使用增强for循环时,不能对元素进行赋值;

int[] arr = {1,2,3};

for(int num : arr) {

num = 0; //不能改变数组的值

}

System.out.println(arr[1]); //2

--------------------------------------------------

可变参数(...):用到函数的参数上,当要操作的同一个类型元素个数不确定的时候,可是用这个方式,这个参数可以接受任意个数的同一类型的数据。

和以前接收数组不一样的是:

以前定义数组类型,需要先创建一个数组对象,再将这个数组对象作为参数传递给函数。现在,直接将数组中的元素作为参数传递即可。底层其实是将这些元素进行数组的封装,而这个封装动作,是在底层完成的,被隐藏了。所以简化了用户的书写,少了调用者定义数组的动作。

如果在参数列表中使用了可变参数,可变参数必须定义在参数列表结尾(也就是必须是最后一个参数,否则编译会失败。)。

如果要获取多个int数的和呢?可以使用将多个int数封装到数组中,直接对数组求和即可。

---------------------------------------------------

静态导入:导入了类中的所有静态成员,简化静态成员的书写。

import static java.util.Collections.*;  //导入了Collections类中的所有静态成员

其他类

System:不可以创建对象,提供了操作标准输入输出设备的属性

out——输出

in ——输入

static Properties getProperties()确定当前系统属性

System.out.println("hello\nWorld");——

System.out.println("hello"+System.getProperty("line.separator")+"world");

public static final LINE_SEPARATOR=System.getProperty("line.separator");//把这个定义成常量

System.out.println(System.getProperty("user.dir"));

Runtime

没有对外提供构造函数——不能new对象,但是有非静态方法,内部创建好了对象,对外提供了获取该对象的方法,该方法肯定是静态的,且返回值是本类——单例设计模式。

Runtime r=Runtime.getRuntime();

Process p=r.exec("notepad.exe");//打开记事本,这个程序在系统中,所以用

//可以用改程序直接打开改程序能打开的文件,比如用播放器打开音乐文件

Process pr=r.exec("notepad.exe C:\\Users\\acer\\Documents\\exercises\\MY_THINK910-1\\集合框架_4.txt");

//如果该程序不在系统设置中,必须使用全路径名

//r.exec("C:\\Program Files\\Tencent\\QQ\\bin\\qq.exe");

Thread.sleep(4000);

p.destroy();

pr.destroy();

Math

Math方法:

ceil ——>向上取整,转成double

floor——>向下取整,转成double

round——>四舍五入,转成double

Random类生成随机数

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值