码农上工Java013-集合

6次阅读

共计 15493 个字符,预计需要花费 39 分钟才能阅读完成。

集合框架(重点理解):用于存储数据的容器。特点:1:对象封装数据,对象多了也需要存储。集合用于存储对象。2:对象的个数确定可以使用数组,但是不确定怎么办?可以用集合。因为集合是可变长度的。
集合和数组的区别:1:数组是固定长度的;集合可变长度的。2:数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型。3:数组存储的元素必须是同一个数据类型;集合存储的对象可以是不同数据类型。
数据结构:就是容器中存储数据的方式。
对于集合容器,有很多种。因为每一个容器的自身特点不同,其实原理在于每个容器的内部数据结构不同。集合容器在不断向上抽取过程中。出现了集合体系。在使用一个体系时,原则:参阅顶层内容。建立底层对象。

–< java.util >– Collection 接口:Collection:|–List:有序(元素存入集合的顺序和取出的顺序一致),元素都有索引。元素可以重复。|–Set:无序(存入和取出顺序有可能不一致),不可以存储重复元素。必须保证元素唯一性。
1,添加:add(object):添加一个元素 addAll(Collection):添加一个集合中的所有元素。2,删除:clear():将集合中的元素全删除,清空集合。remove(obj):删除集合中指定的对象。注意:删除成功,集合的长度会改变。removeAll(collection):删除部分元素。部分元素和传入 Collection 一致。3,判断:boolean contains(obj):集合中是否包含指定元素。boolean containsAll(Collection):集合中是否包含指定的多个元素。boolean isEmpty():集合中是否有元素。4,获取:int size():集合中有几个元素。5,取交集:boolean retainAll(Collection):对当前集合中保留和指定集合中的相同的元素。如果两个集合元素相同,返回 flase;如果 retainAll 修改了当前集合,返回 true。6,获取集合中所有元素:Iterator iterator():迭代器 7,将集合变成数组:
toArray();
–< java.util >– Iterator 接口:迭代器:是一个接口。作用:用于取集合中的元素。boolean hasNext()  如果仍有元素可以迭代,则返回 true。E next()   返回迭代的下一个元素。void remove()  从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。
每一个集合都有自己的数据结构,都有特定的取出自己内部元素的方式。为了便于操作所有的容器,取出元素。将容器内部的取出方式按照一个统一的规则向外提供,这个规则就是 Iterator 接口。也就说,只要通过该接口就可以取出 Collection 集合中的元素,至于每一个具体的容器依据自己的数据结构,如何实现的具体取出细节,这个不用关心,这样就降低了取出元素和具体集合的耦合性。
Iterator it = coll.iterator();// 获取容器中的迭代器对象,至于这个对象是是什么不重要。这对象肯定符合一个规则 Iterator 接口。
public static void main(String[] args) {Collection coll = new ArrayList();coll.add(“abc0”);coll.add(“abc1”);coll.add(“abc2”);//————– 方式 1 ———————-Iterator it = coll.iterator();while(it.hasNext()){System.out.println(it.next());}//————— 方式 2 用此种 ———————-for(Iterator it = coll.iterator();it.hasNext();){System.out.println(it.next());}
}
–< java.util >– List 接口:List 本身是 Collection 接口的子接口,具备了 Collection 的所有方法。现在学习 List 体系特有的共性方法,查阅方法发现 List 的特有方法都有索引,这是该集合最大的特点。
List:有序(元素存入集合的顺序和取出的顺序一致),元素都有索引。元素可以重复。|–ArrayList:底层的数据结构是数组, 线程不同步,ArrayList 替代了 Vector,查询元素的速度非常快。|–LinkedList:底层的数据结构是链表,线程不同步,增删元素的速度非常快。|–Vector:底层的数据结构就是数组,线程同步的,Vector 无论查询和增删都巨慢。
1,添加:add(index,element):在指定的索引位插入元素。addAll(index,collection):在指定的索引位插入一堆元素。2,删除:remove(index):删除指定索引位的元素。返回被删的元素。3,获取:Object get(index):通过索引获取指定元素。int indexOf(obj):获取指定元素第一次出现的索引位,如果该元素不存在返回 -1;所以,通过 -1,可以判断一个元素是否存在。int lastIndexOf(Object o):反向索引指定元素的位置。List subList(start,end):获取子列表。4,修改:Object set(index,element):对指定索引位进行元素的修改。5,获取所有元素:ListIterator listIterator():list 集合特有的迭代器。
List 集合支持对元素的增、删、改、查。
List 集合因为角标有了自己的获取元素的方式:遍历。for(int x=0; x<list.size(); x++){sop(“get:”+list.get(x));}在进行 list 列表元素迭代的时候,如果想要在迭代过程中,想要对元素进行操作的时候,比如满足条件添加新元素。会发生.ConcurrentModificationException 并发修改异常。导致的原因是:集合引用和迭代器引用在同时操作元素,通过集合获取到对应的迭代器后,在迭代中,进行集合引用的元素添加,迭代器并不知道,所以会出现异常情况。如何解决呢?既然是在迭代中对元素进行操作, 找迭代器的方法最为合适. 可是 Iterator 中只有 hasNext,next,remove 方法. 通过查阅的它的子接口,ListIterator, 发现该列表迭代器接口具备了对元素的增、删、改、查的动作。
ListIterator 是 List 集合特有的迭代器。ListIterator it = list.listIterator;// 取代 Iterator it = list.iterator; 方法摘要 void add(E e) 将指定的元素插入列表(可选操作)。boolean hasNext() 以正向遍历列表时,如果列表迭代器有多个元素,则返回 true(换句话说,如果 next 返回一个元素而不是抛出异常,则返回 true)。boolean hasPrevious() 如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。E next() 返回列表中的下一个元素。int nextIndex() 返回对 next 的后续调用所返回元素的索引。E previous() 返回列表中的前一个元素。int previousIndex() 返回对 previous 的后续调用所返回元素的索引。void remove() 从列表中移除由 next 或 previous 返回的最后一个元素(可选操作)。void set(E e) 用指定元素替换 next 或 previous 返回的最后一个元素(可选操作)。
可变长度数组的原理:当元素超出数组长度,会产生一个新数组,将原数组的数据复制到新数组中,再将新的元素添加到新数组中。ArrayList:是按照原数组的 50% 延长。构造一个初始容量为 10 的空列表。Vector:是按照原数组的 100% 延长。
注意:对于 list 集合,底层判断元素是否相同,其实用的是元素自身的 equals 方法完成的。所以建议元素都要复写 equals 方法,建立元素对象自己的比较相同的条件依据。
LinkedList:的特有方法。addFirst();addLast(); 在 jdk1.6 以后。offerFirst();offerLast();
getFirst(): 获取链表中的第一个元素。如果链表为空,抛出 NoSuchElementException;getLast(); 在 jdk1.6 以后。peekFirst(); 获取链表中的第一个元素。如果链表为空,返回 null。peekLast();
removeFirst():获取链表中的第一个元素,但是会删除链表中的第一个元素。如果链表为空,抛出 NoSuchElementExceptionremoveLast(); 在 jdk1.6 以后。pollFirst(); 获取链表中的第一个元素,但是会删除链表中的第一个元素。如果链表为空,返回 null。
pollLast();
–< java.util >– Set 接口:Set 接口中的方法和 Collection 中方法一致的。Set 接口取出方式只有一种,迭代器。|–HashSet:底层数据结构是哈希表,线程是不同步的。无序,高效;HashSet 集合保证元素唯一性:通过元素的 hashCode 方法,和 equals 方法完成的。当元素的 hashCode 值相同时,才继续判断元素的 equals 是否为 true。如果为 true,那么视为相同元素,不存。如果为 false,那么存储。如果 hashCode 值不同,那么不判断 equals,从而提高对象比较的速度。
|–LinkedHashSet:有序,hashset 的子类。
|–TreeSet:对 Set 集合中的元素的进行指定顺序的排序。不同步。TreeSet 底层的数据结构就是二叉树。
哈希表的原理:1,对对象元素中的关键字(对象中的特有数据),进行哈希算法的运算,并得出一个具体的算法值,这个值 称为哈希值。2,哈希值就是这个元素的位置。3,如果哈希值出现冲突,再次判断这个关键字对应的对象是否相同。如果对象相同,就不存储,因为元素重复。如果对象不同,就存储,在原来对象的哈希值基础 + 1 顺延。4,存储哈希值的结构,我们称为哈希表。5,既然哈希表是根据哈希值存储的,为了提高效率,最好保证对象的关键字是唯一的。这样可以尽量少的判断关键字对应的对象是否相同,提高了哈希表的操作效率。
对于 ArrayList 集合,判断元素是否存在,或者删元素底层依据都是 equals 方法。对于 HashSet 集合,判断元素是否存在,或者删除元素,底层依据的是 hashCode 方法和 equals 方法。
TreeSet: 用于对 Set 集合进行元素的指定顺序排序,排序需要依据元素自身具备的比较性。如果元素不具备比较性,在运行时会发生 ClassCastException 异常。所以需要元素实现 Comparable 接口,强制让元素具备比较性,复写 compareTo 方法。依据 compareTo 方法的返回值,确定元素在 TreeSet 数据结构中的位置。TreeSet 方法保证元素唯一性的方式:就是参考比较方法的结果是否为 0,如果 return 0,视为两个对象重复,不存。
注意:在进行比较时,如果判断元素不唯一,比如,同姓名,同年龄,才视为同一个人。在判断时,需要分主要条件和次要条件,当主要条件相同时,再判断次要条件,按照次要条件排序。
TreeSet 集合排序有两种方式,Comparable 和 Comparator 区别:1:让元素自身具备比较性,需要元素对象实现 Comparable 接口,覆盖 compareTo 方法。2:让集合自身具备比较性,需要定义一个实现了 Comparator 接口的比较器,并覆盖 compare 方法,并将该类对象作为实际参数传递给 TreeSet 集合的构造函数。第二种方式较为灵活。

Map 集合:|–Hashtable:底层是哈希表数据结构,是线程同步的。不可以存储 null 键,null 值。|–HashMap:底层是哈希表数据结构,是线程不同步的。可以存储 null 键,null 值。替代了 Hashtable.|–TreeMap:底层是二叉树结构,可以对 map 集合中的键进行指定顺序的排序。
Map 集合存储和 Collection 有着很大不同:Collection 一次存一个元素;Map 一次存一对元素。Collection 是单列集合;Map 是双列集合。Map 中的存储的一对元素:一个是键,一个是值,键与值之间有对应 (映射) 关系。特点:要保证 map 集合中键的唯一性。
1,添加。put(key,value):当存储的键相同时,新的值会替换老的值,并将老值返回。如果键没有重复,返回 null。void putAll(Map);2,删除。void clear():清空 value remove(key):删除指定键。3,判断。boolean isEmpty():boolean containsKey(key):是否包含 keyboolean containsValue(value):是否包含 value4,取出。int size():返回长度 value get(key):通过指定键获取对应的值。如果返回 null,可以判断该键不存在。当然有特殊情况,就是在 hashmap 集合中,是可以存储 null 键 null 值的。Collection values():获取 map 集合中的所有的值。5,想要获取 map 中的所有元素:原理:map 中是没有迭代器的,collection 具备迭代器,只要将 map 集合转成 Set 集合,可以使用迭代器了。之所以转成 set,是因为 map 集合具备着键的唯一性,其实 set 集合就来自于 map,set 集合底层其实用的就是 map 的方法。★ 把 map 集合转成 set 的方法:Set keySet();Set entrySet();// 取的是键和值的映射关系。Entry 就是 Map 接口中的内部接口;
为什么要定义在 map 内部呢?entry 是访问键值关系的入口,是 map 的入口,访问的是 map 中的键值对。
取出 map 集合中所有元素的方式一:keySet()方法。可以将 map 集合中的键都取出存放到 set 集合中。对 set 集合进行迭代。迭代完成,再通过 get 方法对获取到的键进行值的获取。Set keySet = map.keySet();Iterator it = keySet.iterator();while(it.hasNext()) {Object key = it.next();Object value = map.get(key);System.out.println(key+”:”+value);
}
取出 map 集合中所有元素的方式二:entrySet()方法。Set entrySet = map.entrySet();Iterator it = entrySet.iterator();while(it.hasNext()) {Map.Entry me = (Map.Entry)it.next();System.out.println(me.getKey()+”::::”+me.getValue());
}
使用集合的技巧:看到 Array 就是数组结构,有角标,查询速度很快。看到 link 就是链表结构:增删速度快,而且有特有方法。addFirst;addLast;removeFirst();removeLast();getFirst();getLast();看到 hash 就是哈希表,就要想要哈希值,就要想到唯一性,就要想到存入到该结构的中的元素必须覆盖 hashCode,equals 方法。看到 tree 就是二叉树,就要想到排序,就想要用到比较。比较的两种方式:一个是 Comparable:覆盖 compareTo 方法;一个是 Comparator:覆盖 compare 方法。LinkedHashSet,LinkedHashMap: 这两个集合可以保证哈希表有存入顺序和取出顺序一致,保证哈希表有序。
集合什么时候用?当存储的是一个元素时,就用 Collection。当存储对象之间存在着映射关系时,就使用 Map 集合。
保证唯一,就用 Set。不保证唯一,就用 List。
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 map2)、增强 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. 迭代出所有的 entrywhile(iter.hasNext()) {Map.Entry entry = (Entry) iter.next();String key = (String) entry.getKey(); // 分别获得 key 和 valueString 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 依次表示 EntrySystem.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 类中的所有静态成员
枚举:关键字 enum 问题:对象的某个属性的值不能是任意的,必须为固定的一组取值其中的某一个;解决办法:1)、在 setGrade 方法中做判断,不符合格式要求就抛出异常;2)、直接限定用户的选择,通过自定义类模拟枚举的方式来限定用户的输入,写一个 Grade 类,私有构造函数,对外提供 5 个静态的常量表示类的实例;3)、jdk5 中新定义了枚举类型,专门用于解决此类问题;
4)、枚举就是一个特殊的 java 类,可以定义属性、方法、构造函数、实现接口、继承类;
自动拆装箱:java 中数据类型分为两种:基本数据类型 引用数据类型 (对象) 在 java 程序中所有的数据都需要当做对象来处理,针对 8 种基本数据类型提供了包装类,如下:int –> Integerbyte –> Byteshort –> Shortlong –> Longchar –> Characterdouble –> Doublefloat –> Floatboolean –> Boolean
jdk5 以前基本数据类型和包装类之间需要互转:基本 — 引用 Integer x = new Integer(x); 引用 — 基本 int num = x.intValue();1)、Integer x = 1; x = x + 1; 经历了什么过程?装箱 à 拆箱 à 装箱;2)、为了优化,虚拟机为包装类提供了缓冲池,Integer 池的大小 -128~127 一个字节的大小;
3)、String 池:Java 为了优化字符串操作 提供了一个缓冲池;
泛型:jdk1.5 版本以后出现的一个安全机制。表现格式:< > 好处:1:将运行时期的问题 ClassCastException 问题转换成了编译失败,体现在编译时期,程序员就可以解决问题。2:避免了强制转换的麻烦。
只要带有 <> 的类或者接口,都属于带有类型参数的类或者接口,在使用这些类或者接口时,必须给 <> 中传递一个具体的引用数据类型。
泛型技术:其实应用在编译时期,是给编译器使用的技术,到了运行时期,泛型就不存在了。为什么? 因为泛型的擦除:也就是说,编辑器检查了泛型的类型正确后,在生成的类文件中是没有泛型的。在运行时,如何知道获取的元素类型而不用强转呢?泛型的补偿:因为存储的时候,类型已经确定了是同一个类型的元素,所以在运行时,只要获取到该元素的类型,在内部进行一次转换即可,所以使用者不用再做转换动作了。
什么时候用泛型类呢?
当类中的操作的引用数据类型不确定的时候,以前用的 Object 来进行扩展的,现在可以用泛型来表示。这样可以避免强转的麻烦,而且将运行问题转移到的编译时期。
泛型在程序定义上的体现:// 泛型类:将泛型定义在类上。class Tool<Q> {private Q obj;public void setObject(Q obj) {this.obj = obj;}public Q getObject() {return obj;}}// 当方法操作的引用数据类型不确定的时候,可以将泛型定义在方法上。public <W> void method(W w) {System.out.println(“method:”+w);}// 静态方法上的泛型:静态方法无法访问类上定义的泛型。如果静态方法操作的引用数据类型不确定的时候,必须要将泛型定义在方法上。public static <Q> void function(Q t) {System.out.println(“function:”+t);}// 泛型接口.interface Inter<T> {void show(T t);}class InterImpl<R> implements Inter<R> {public void show(R r) {System.out.println(“show:”+r);}
}
泛型中的通配符:可以解决当具体类型不确定的时候,这个通配符就是 ?;当操作类型时,不需要使用类型的具体功能时,只使用 Object 类中的功能。那么可以用 ? 通配符来表未知类型。
泛型限定:上限:?extends E:可以接收 E 类型或者 E 的子类型对象。下限:?super E:可以接收 E 类型或者 E 的父类型对象。
上限什么时候用:往集合中添加元素时,既可以添加 E 类型对象,又可以添加 E 的子类型对象。为什么?因为取的时候,E 类型既可以接收 E 类对象,又可以接收 E 的子类型对象。
下限什么时候用:当从集合中获取元素进行操作的时候,可以用当前元素的类型接收,也可以用当前元素的父类型接收。
泛型的细节:1)、泛型到底代表什么类型取决于调用者传入的类型,如果没传,默认是 Object 类型;2)、使用带泛型的类创建对象时,等式两边指定的泛型必须一致;原因:编译器检查对象调用方法时只看变量,然而程序运行期间调用方法时就要考虑对象具体类型了;3)、等式两边可以在任意一边使用泛型,在另一边不使用(考虑向后兼容);ArrayList<String> al = new ArrayList<Object>(); // 错 // 要保证左右两边的泛型具体类型一致就可以了,这样不容易出错。ArrayList<? extends Object> al = new ArrayList<String>();al.add(“aa”); // 错 // 因为集合具体对象中既可存储 String,也可以存储 Object 的其他子类,所以添加具体的类型对象不合适,类型检查会出现安全问题。?extends Object 代表 Object 的子类型不确定,怎么能添加具体类型的对象呢?public static void method(ArrayList<? extends Object> al) {al.add(“abc”); // 错 // 只能对 al 集合中的元素调用 Object 类中的方法,具体子类型的方法都不能用,因为子类型不确定。
}
API— java.lang.System: 属性和行为都是静态的。long currentTimeMillis(); // 返回当前时间毫秒值 exit(); // 退出虚拟机 Properties getProperties() ; // 获取当前系统的属性信息
Properties prop = System.getProperties(); // 获取系统的属性信息,并将这些信息存储到 Properties 集合中。
System.setProperty(“myname”,” 毕老师 ”); // 给系统属性信息集添加具体的属性信息 // 临时设置方式:运行 jvm 时,可以通过 jvm 的参数进行系统属性的临时设置,可以在 java 命令的后面加入 –D<name>=<value> 用法:java –Dmyname= 小明 类名。
String name = System.getProperty(“os.name”);// 获取指定属性的信息
// 想要知道该系统是否是该软件所支持的系统中的一个。Set<String> hs = new HashSet<String>();hs.add(“Windows XP”);hs.add(“Windows 7”);if(hs.contains(name))System.out.println(“ 可以支持 ”);else
System.out.println(“ 不支持 ”);
API— java.lang.Runtime: 类中没有构造方法,不能创建对象。但是有非静态方法。说明该类中应该定义好了对象,并可以通过一个 static 方法获取这个对象。用这个对象来调用非静态方法。这个方法就是 static Runtime getRuntime();
这个 Runtime 其实使用单例设计模式进行设计。
class RuntimeDemo {public static void main(String[] args) throws Exception {Runtime r = Runtime.getRuntime();Process p = r.exec(“notepad.exe SystemDemo.java”);// 运行指定的程序 Thread.sleep(4000);p.destroy(); // 杀掉进程}
}
API— java.util.Math: 用于数学运算的工具类,属性和行为都是静态的。该类是 final 不允许继承。
static double ceil(double a) ; // 返回大于指定数值的最小整数 static double floor(double a) ; // 返回小于指定数值的最大整数 static long round(double a) ; // 四舍五入成整数 static double pow(double a, double b) ; // a 的 b 次幂 static double random(); // 返回 0~1 的伪随机数
public static void main(String[] args) {Random r = new Random();for(int x=0; x<10; x++) {//double d = Math.floor(Math.random()*10+1);//int d = (int)(Math.random()*10+1);int d = r.nextInt(10)+1;System.out.println(d);}
}
API— java.util.Date:日期类,月份从 0 -11;/* 日期对象和毫秒值之间的转换。1,日期对象转成毫秒值。Date 类中的 getTime 方法。2,如何将获取到的毫秒值转成具体的日期呢?Date 类中的 setTime 方法。也可以通过构造函数。*/// 日期对象转成毫秒值 Date d = new Date();long time1 = d.getTime();long time2 = System.currentTimeMillis(); / / 毫秒值。
// 毫秒值转成具体的日期 long time = 1322709921312l;Date d = new Date();d.setTime(time);/* 将日期字符串转换成日期对象:使用的就是 DateFormat 方法中的 Date parse(String source);*/public static void method() throws Exception {String str_time = “2011/10/25”;DateFormat df = new SimpleDateFormat(“yyyy/MM/dd”); //SimpleDateFormat 作为可以指定用户自定义的格式来完成格式化。Date d = df.parse(str_time);}/* 如果不需要使用特定的格式化风格,完全可以使用 DateFormat 类中的静态工厂方法获取具体的已经封装好风格的对象。getDateInstance();getDateTimeInstance();*/Date d = new Date();DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);df = DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);String str_time = df.format(d);
// 将日期对象转换成字符串的方式:DateFormat 类中的 format 方法。
// 创建日期格式对象。
DateFormat df = new SimpleDateFormat(); // 该对象的建立内部会封装一个默认的日期格式。11-12-1 下午 1:48// 如果想要自定义日期格式的话。可使用 SimpleDateFormat 的构造函数。将具体的格式作为参数传入到构造函数中。如何表示日期中年的部分呢?可以必须要参与格式对象文档。df = new SimpleDateFormat(“yyyy 年 MM 月 dd 日 HH:mm:ss”);// 调用 DateFormat 中的 format 方法。对已有的日期对象进行格式化。
String str_time = df.format(d);
API— java.util. Calendar:日历类 public static void method(){Calendar c = Calendar.getInstance();System.out.println(c.get(Calendar.YEAR)+” 年 ”+(c.get(Calendar.MONTH)+1)+” 月 ”+getNum(c.get(Calendar.DAY_OF_MONTH))+” 日 ”+” 星期 ”+getWeek(c.get(Calendar.DAY_OF_WEEK)));}public static String getNum(int num){return num>9 ? num+”” : “0”+num;}public static String getWeek(int index){/* 查表法:建立数据的对应关系. 最好:数据个数是确定的,而且有对应关系。如果对应关系的一方,是数字,而且可以作为角标,那么可以通过数组来作为表。*/String[] weeks = {“”,” 日 ”,” 一 ”,” 二 ”,” 三 ”,” 四 ”,” 五 ”,” 六 ”};return weeks[index];
}

正文完
 0