Java语言基础-常用对象API(二)泛型、Map集合
泛型
是JDK1.5出现的安全机制。
好处:
1.将运行时期的问题ClassCastException转到了编译时期;
2.避免了强制转换的麻烦;
<> 什么时候用? 当操作的引用数据类型不确定的时候,就使用<>,将要操作的引用数据类型传入即可。
<>就是一个用于接收具体引用数据类型的参数范围。
在程序中,只要用到了带有<>的类或者借口,就要明确传入的具体引用数据类型;
泛型技术是给编译器使用的技术,用于在编译时期确保类型的安全;
运行时,会将泛型去掉,生成的class文件中不带有泛型。这个称为泛型的擦除。
为什么擦除? 因为为了兼容运行时的类加载器。
泛型的补偿:在运行时,通过获取元素的类型对进行转换动作,不需要使用者再进行强制转换。
当方法静态时,不能访问类上定义的泛型,如果静态方法使用方法, 只能将泛型定义在方法上。
当定义了泛型时,不能使用具体的方法。
泛型使用示例:
package cn.ticast.p4.generic.define.demo; public class GenericDemo4 { public static void main(String[] args){ Tool<String> tool=new Tool<String>(); tool.show(new Integer(4)); tool.show("abc"); tool.print("hahah"); Tool.method("haha"); } }
package cn.ticast.p4.generic.define.demo; //jdk1.5以后,使用泛型来接收类中要操作的引用数据类型 //泛型类:当类中操作的引用数据类型不确定时,使用泛型来表示 public class Tool<QQ>{ private QQ q; public QQ getObject() { return q; } public void setObject(QQ object) { this.q = object; } /** * 将泛型定义在方法上 * @param str */ public <w> void show(w str){ System.out.println("show:"+str); } public void print(QQ str){ //System.out.println("print:"+str.length());//错误,当定义了泛型时,不能使用具体的方法。 System.out.println("print:"+str); } /** * 当方法静态时,不能访问类上定义的泛型,如果静态方法使用泛型, * 只能将泛型定义在方法上 */ public static <Y> void method(Y obj){//静态方法不需要对象 System.out.println("method:"+obj); } }
泛型接口示例:
package cn.ticast.p4.generic.define.demo; public class GenericDefineDemo5 { public static void main(String[] args) { InterImpl1 in=new InterImpl1(); in.show("abc"); InterImpl2<Integer> in2=new InterImpl2<Integer>(); in2.show(5); } } //泛型接口,将泛型定义在接口上 interface Inter<T>{ public void show(T t); } class InterImpl1 implements Inter<String>{ public void show(String str){ System.out.println("show:"+str); } } class InterImpl2 <Q> implements Inter<Q>{ public void show(Q q){ System.out.println("show:"+q); } }
泛型的通配符:? 未知类型
可以对类型进行限定 ? extends E:接收E类型或者子类型对象,上限
? super E:接收E类型或者E的福类型,下限
一般来说,在存储元素的时候使用上限,因为这样都是按照上限类型来运算的,不会出现类型安全隐患。
class TreeSet<E>
{
Tree(Comparator<? super E> comp);
}
什么时候使用下限?通常对集合中的元素进行取出操作时,可以使用下限。
上限体现:
package cn.ticast.p5.generic.advance.demo; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import cn.itcast.p2.bean.Person; import cn.itcast.p2.bean.Student; import cn.itcast.p2.bean.Worker; public class GenericAdvanceDemo3 { /** * @param args */ public static void main(String[] args) { ArrayList<Person> al1 = new ArrayList<Person>(); al1.add(new Person("abc", 30)); al1.add(new Person("hehe", 34)); ArrayList<Student> al2 = new ArrayList<Student>(); al2.add(new Student("stu1", 11)); al2.add(new Student("stu2", 22)); ArrayList<Worker> al3 = new ArrayList<Worker>(); al3.add(new Worker("stu1", 11)); al3.add(new Worker("stu2", 22)); ArrayList<String> al4=new ArrayList<String>(); al4.add("abcdefg"); // al1.addAll(al4);//有泛型限定之后,al4不能添加到al1(类型不匹配,此处只能是Person及其子类);如果没有泛型限定,能够传入,但是有安全隐患,取出时会出错 al1.addAll(al2);//有泛型限定之后,能够添加。Student是Person的子类 al1.addAll(al3); // printCollection(al); // printCollection(al2); } /* * 一般在存储元素的时候使用上限,以为这样都是按照上限类型来运算的,不会出现类型安全隐患 */ class MyCollection<E>{ public void add(E e){ } public void addAll(MyCollection<? extends E> al){ } } }
下限体现:
package cn.ticast.p5.generic.advance.demo; import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; import cn.itcast.p2.bean.Person; import cn.itcast.p2.bean.Student; import cn.itcast.p2.bean.Worker; public class GenericAdvanceDemo4 { /** * @param args */ public static void main(String[] args) { TreeSet<Person> al1 = new TreeSet<Person>(new CompByName()); al1.add(new Person("abc4", 30)); al1.add(new Person("abc1", 34)); al1.add(new Person("abc2", 38)); TreeSet<Student> al2 = new TreeSet<Student>(new CompByStName()); al2.add(new Student("stu1", 11)); al2.add(new Student("stu7", 20)); al2.add(new Student("stu2", 22)); TreeSet<Worker> al3 = new TreeSet<Worker>(); al3.add(new Worker("stu1", 11)); al3.add(new Worker("stu2", 22)); TreeSet<String> al4=new TreeSet<String>(); al4.add("abcdefg"); // al1.addAll(al4); // al1.addAll(al2); // al1.addAll(al3); // System.out.println(al1.size()); Iterator<Student> it=al2.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } } /* * class TreeSet<E> * {Tree(Comparator<? super E> comp);} * * 什么时候使用下限?通常对集合中的元素进行取出操作时,可以使用下限。 */ class CompByName implements Comparator<Person>{ @Override public int compare(Person o1, Person o2) { int temp=o1.getName().compareTo(o2.getName()); return temp==0?o1.getAge()-o2.getAge():temp; } } class CompByStName implements Comparator<Student>{ @Override public int compare(Student o1, Student o2) { int temp=o1.getName().compareTo(o2.getName()); return temp==0?o1.getAge()-o2.getAge():temp; } }
通配符应用:
package cn.ticast.p5.generic.advance.demo; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import cn.itcast.p2.bean.Person; public class GenericAdvanceDemo5 { /** * @param args */ public static void main(String[] args) { ArrayList<Person> al1 = new ArrayList<Person>(); al1.add(new Person("abc", 30)); al1.add(new Person("abc4", 34)); ArrayList<Person> al2 = new ArrayList<Person>(); al2.add(new Person("abc22222", 30)); al2.add(new Person("abc422222", 34)); al1.containsAll(al2); ArrayList<String> al4 = new ArrayList<String>(); al4.add("abcdefg"); al4.add("abc"); al1.containsAll(al4); Iterator<Person> it = al1.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } public static void printCollection(Collection<?> al) { Iterator<?> it = al.iterator();// Collection<? extends while (it.hasNext()) { System.out.println(it.next()); } } } class MyCollection2<E>{ public boolean containsAll(Collection<?> coll){ return true; } }
集合查阅技巧:
是否需要唯一?
需要:Set
是否需要指定顺序?
需要:TreeSet
不需要:HashSet
想要一个和存储一致的顺序(有序):LinkedHashSet
不需要:List
是否需要频繁增删?
需要:LinkedList
不需要:ArrayList
如何记住每个容器的结构和所属体系?
看名字:
List
|--ArrayList
|--LinkedList
Set
|--HashSet
|--TreeSet
后缀名就是该集合所属的体系。
前缀名就是该集合的数据结构。
array,数组,查询速度快,有脚标;
link,链表,增删速度快,add、get、remove、first last方法;
hash,哈希表,唯一性,元素需要覆盖hashCode方法和equals方法;
tree,二叉树,排序,两个接口Comparable、Comparator;
而且通常这些常用的结合容器都是不同步的。
Map:一次添加一对元素,Collection一次添加一个元素。
Map也称为双列集合,Collection称为单列集合。
特点:
-Map集合中存储的是键值对。
-Map集合中必须保证键的唯一性。
常用方法:
1.添加
value put(K key, V value); //返回上一个与key关联的值,如果没有则返回null。
2.删除
void clear();//清空map集合
value remove(Object key); //根据指定的key,删除这个键值对
3.判断
boolean containsKey(key);//如果此映射包含指定键的映射关系,则返回 true。
boolean containsValue(key);//如果此映射将一个或多个键映射到指定值,则返回 true。
boolean isEmpty();//如果此映射未包含键-值映射关系,则返回 true。
4.获取
value get(Object key); //通过键获取值,如果没有该键则返回null;可以通过返回null,来判断是否包含指定键。
int size();//获取键值对的个数。
Set<K> keySet();// 返回此映射中包含的键的 Set 视图。
Set<Map.Entry<K,V>> entrySet();//返回此映射中包含的映射关系的 Set 视图。
public static interface Map.Entry<K,V>映射项(键-值对)。
Map.entrySet 方法返回映射的 collection 视图,其中的元素属于此类。
Collection<V> values();//返回此映射中包含的值的 Collection 视图。
Map常见方法示例:
package cn.ticast.p6.map.demo; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class MapDemo { public static void main(String[] args) { Map<Integer, String> map = new HashMap<Integer, String>(); // method(map); method_2(map); } public static void method_2(Map<Integer, String> map) { map.put(8, "wangwu"); map.put(2, "zhaoliu"); map.put(7, "xiaoqiang"); map.put(6, "wangcai"); //只要姓名,不要键 Collection<String> values = map.values(); Iterator<String> it3 = values.iterator(); while (it3.hasNext()) { System.out.println(it3.next()); } /* * 第二种 通过Map转成Set就可以迭代 找到了另一个方法:entrySet * 该方法将键和值的映射关系作为对象存储到了Set集合中,而这个映射关系的类型就是Map.Entry类型 */ Set<Map.Entry<Integer, String>> entrySet = map.entrySet(); Iterator<Map.Entry<Integer, String>> it2 = entrySet.iterator(); while (it2.hasNext()) { Map.Entry<Integer, String> me = it2.next(); Integer key = me.getKey(); String value = me.getValue(); System.out.println(key + ":" + value); } /* * 第一种 取出map中的所有元素 原理:先通过keySet方法,获取map中所有的键所在的Set集合,再通过Set的迭代器, * 获取到每一个键,从而用map的get方法获取每个键对应的值 */ // Set<Integer> keySet = map.keySet(); // Iterator<Integer> it1 = keySet.iterator(); // while (it1.hasNext()) { // Integer key = it1.next();// 通过迭代器获取每个键 // String value = map.get(key);// 使用get方法,通过每个键获取对应的值 // System.out.println(key + ":" + value); // } } public static void method(Map<Integer, String> map) {// 序号和姓名 // 添加元素 System.out.println(map.put(8, "wangcai"));// null System.out.println(map.put(8, "xiaoqiang"));// wangcai,存相同键,值会覆盖 map.put(2, "zhangsan"); map.put(7, "zhaoliu"); // 删除 // System.out.println("remove:"+map.remove(2)); // 判断 System.out.println("contains key:" + map.containsKey(7)); // 获取 System.out.println("get:" + map.get(8)); System.out.println(map); } }
Map常用的子类对象:
|--HashTable :内部结构是哈希表,是同步的。不允许null作为键和值※
|--Properties:用来存储简直对型的配置文件的信息。可以和IO技术相结合、
|--HashMap :内部结构是哈希表,不是同步的。允许null作为键和值※
|--TreeMap :内部结构是二叉树,不是同步的。可以对Map集合中的键进行排序。
HashMap应用示例:
package cn.ticast.p6.hashmap.demo; import java.util.HashMap; import java.util.Iterator; import cn.itcast.p2.bean.Student; public class HashMapDemo { public static void main(String[] args) { /* * 将学生对象和学生的归属地,通过键与值存储到map集合中 */ HashMap<Student, String> hm = new HashMap<Student, String>(); hm.put(new Student("lisi", 38), "北京"); hm.put(new Student("zhaoliu", 24), "上海"); hm.put(new Student("xiaoqiang",31), "沈阳"); hm.put(new Student("wangcai", 28), "大连"); hm.put(new Student("zhaoliu", 24), "铁岭"); Iterator<Student> it = hm.keySet().iterator(); while (it.hasNext()) { Student key = it.next(); String value = hm.get(key); System.out.println(key.getName() + ":" + key.getAge() + "----" + value); } } }
TreeMap应用示例:
package cn.ticast.p8.treemap.demo; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; import cn.itcast.p2.bean.Student; import cn.ticast.p3.comparator.ComparatorByName; public class TreeMapDemo { public static void main(String[] args) { /* * 将学生对象和学生的归属地,通过键与值存储到map集合中 * 使用比较器Comparator,按姓名排序 */ TreeMap<Student, String> tm = new TreeMap<Student, String>(new ComparatorByName()); tm.put(new Student("lisi", 38), "北京"); tm.put(new Student("zhaoliu", 24), "上海"); tm.put(new Student("xiaoqiang", 31), "沈阳"); tm.put(new Student("wangcai", 28), "大连"); tm.put(new Student("zhaoliu", 24), "铁岭"); Iterator<Map.Entry<Student, String>> it = tm.entrySet().iterator(); while (it.hasNext()) { Map.Entry<Student, String> me = it.next(); Student key = me.getKey(); String value = me.getValue(); System.out.println(key.getName() + ":" + key.getAge() + "----" + value); } } } package cn.ticast.p3.comparator; import java.util.Comparator; import cn.itcast.p2.bean.Person; public class ComparatorByName/*extends Object*/ implements Comparator<Person> { @Override public int compare(Person o1, Person o2) { int temp=o1.getName().compareTo(o2.getName()); return temp==0?o1.getAge()-o2.getAge():temp; } }
LinkedHashMap:使用LinkedHashMap,则有序(存取顺序相同)
LinkedHashMap应用示例:
package cn.itcast.p1.map.demo; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; public class LinkedHashmapDemo { public static void main(String[] args) { HashMap<Integer, String> hm = new LinkedHashMap<Integer, String>(); hm.put(7, "zhouqi"); hm.put(3, "zhangsan"); hm.put(1, "qianyi"); hm.put(5, "wangwu"); Iterator<Map.Entry<Integer, String>> it = hm.entrySet().iterator(); while (it.hasNext()) { Map.Entry<Integer, String> me = it.next(); Integer key = me.getKey(); String value = me.getValue(); System.out.println(key + ":" + value); } } }
Map集合练习:
package cn.itcast.p1.map.test; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; /* * 练习: * "fdqavchsacdfs"获取该字符串中,每一个字母出现的次数。 * 要求打印的结果是a{2}b{1}...; * 思路: * 对于结果的分析发现,字母和次数之间存在着映射的关系,而且这种关系很多 * 所以需要存储,能存储映射关系的容器有数组和Map结合 * 关系一方是否是有序编号?否 * 那就使用Map集合。又发现可以保证唯一性的一方具备着顺序,如a、b、c…… * 所以可以使用TreeMap集合。 * * 这个集合中,最终应该存储的是字母和次数的对应关系 * 1.因为操作的是字符串中的字母,所以先将字符串变为字符数组; * 2.遍历字符数组,用每一个字母作为键去查Map集合这个表; * 如果该字母键不存在,则将该字母作为键,1作为值存储到Map集合中; * 如果该字母键存在,则将该字母对应的值取出,并自增,再将该字母和+1后的值存储到Map集合中; * 键相同,值会覆盖。这样,就记录住了该字母的次数; * 3.遍历结束,Map集合中就记录了所有字母出现的次数。 */ public class MapTest { public static void main(String[] args) { String str = "fd++qa--vc hsacdfs"; String s = getCahrCount(str); System.out.println(s); } public static String getCahrCount(String str) { // 将字符串变成字符数组 char[] chs = str.toCharArray(); // 定义Map集合表 Map<Character, Integer> map = new TreeMap<Character, Integer>(); // 遍历 for (int i = 0; i < chs.length; i++) { if(!(chs[i]>='a'&&chs[i]<='z'||chs[i]>='A'&&chs[i]<='Z')) continue; // 将数组中的数组作为键去查Map表 Integer value = map.get(chs[i]); // 判断值是否为null int count = 1; if (value != null) { count = value + 1; } map.put(chs[i], count); /* * if(value==null){ map.put(chs[i], 1); }else{ map.put(chs[i], * value+1); } */ } return mapToString(map); } private static String mapToString(Map<Character, Integer> map) { StringBuilder sb=new StringBuilder(); Iterator<Character> it=map.keySet().iterator(); while(it.hasNext()){ Character key=it.next(); Integer value=map.get(key); sb.append(key+"{"+value+"}"); } return sb.toString(); } } package cn.itcast.p1.map.test; import java.util.HashMap; import java.util.Map; public class MapTest2 { public static void main(String[] args) { /* * Map在有映射关系时,可以优先考虑 * * 在查表法中的应用较为多见 */ String week = getWeek(1); System.out.println(week); System.out.println(getWeekByMap(week)); } public static String getWeekByMap(String week) { Map<String, String> map = new HashMap<String, String>(); map.put("星期一","Mon"); map.put("星期二","Tus"); map.put("星期三","Wes"); map.put("星期日","Sun"); map.put("星期天","Sun"); return map.get(week); } public static String getWeek(int week) { if (week < 1 || week > 7) throw new RuntimeException("没有对应的星期,请重新输入"); String[] weeks = { "", "星期一", "星期二" }; return weeks[week]; } }
Collections工具类
Collections是集合框架的工具类,里边的方法都是静态的。
static <T extends Comparable<? super T>> void sort(List<T> list)
根据元素的自然顺序 对指定列表按升序进行排序。
static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key)
使用二分搜索法搜索指定列表,以获得指定对象。
使用二分搜索法搜索指定列表,以获得指定对象。在进行此调用之前,必须根据列表元素的自然顺序对列表进行升序排序(通过 sort(List) 方法)。如果没有对列表进行排序,则结果是不确定的。如果列表包含多个等于指定对象的元素,则无法保证找到的是哪一个。
如果搜索键包含在列表中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。
static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)
根据元素的自然顺序,返回给定 collection 的最大元素。
static <T> Comparator<T> reverseOrder()
返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。
static void reverse(List<?> list)
反转指定列表中元素的顺序。
static <T> boolean replaceAll(List<T> list, T oldVal, T newVal)
使用另一个值替换列表中出现的所有某一指定值。
static <T> void fill(List<? super T> list, T obj)
使用指定元素替换指定列表中的所有元素。
static void shuffle(List<?> list)
使用默认随机源对指定列表进行置换。
static <T> Enumeration<T> enumeration(Collection<T> c)
返回一个指定 collection 上的枚举。
※
给非同步的集合加锁
List list=new ArrayList();//非同步的
list=MyCollections.Synchronized(list);//返回一个同步的list
class MyCollections{ public static List synchronized(List list){ return new MyList(list); } } private class MyList implements List{ private List list; pirvate static final Object lock=new Object(); MyList(List list){ this.list=list; } public boolean add(Object obj){ synchronized(lock) { return list.add(obj); } } public boolean remove(Object obj){ synchronized(lock) { return list.remove(obj); } } }
static <T> Collection<T> synchronizedCollection(Collection<T> c)
返回指定 collection 支持的同步(线程安全的)collection。
static <T> List<T> synchronizedList(List<T> list)
返回指定列表支持的同步(线程安全的)列表。
static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)
返回由指定映射支持的同步(线程安全的)映射。
static <T> Set<T> synchronizedSet(Set<T> s)
返回指定 set 支持的同步(线程安全的)set。
static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m)
返回指定有序映射支持的同步(线程安全的)有序映射。
static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s)
返回指定有序 set 支持的同步(线程安全的)有序 set。
Arrays工具类
Arrays集合框架的工具类,里面的方法都是静态的。
重点: List asList(数组) 将数组转成集合
好处:可以使用结合的方法操作数组中的元素
注意:数组的长度是固定的,所以对于集合的增删方法是不可以使用的,
否则会发生UnsupportedOperationException。
如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。
如果数组中的元素是基本类型数值,那么会将数组作为集合中的元素进行存储。
package cn.itcast.p3.toolclass.arrays.demo; import java.util.Arrays; import java.util.List; //数组转成集合 public class ArraysDemo { /** * @param args */ public static void main(String[] args) { // int[] arr={3,1,5,6,3,6}; // System.out.println(Arrays.toString(arr)); System.out.println("demo_1"); demo_1(); System.out.println("demo_2"); demo_2(); } public static void demo_2() { /* * 如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。 * 如果数组中的元素是基本类型数值,那么会将数组作为集合中的元素进行存储。 */ int[] arr = { 31, 11, 51, 61 }; List<int[]> list = Arrays.asList(arr); System.out.println(list); } /** * */ private static void demo_1() { String[] arr = { "abc", "haha", "xixi" }; boolean b = myContains(arr, "xixi"); System.out.println("contains:" + b); List<String> list = Arrays.asList(arr); // list.add("hehe");//数组的长度是固定的,所以对于集合的增删方法是不可以使用的, // 否则会发生UnsupportedOperationException。 boolean b1 = myContains(arr, "xixi"); System.out.println("list contains:" + b1); System.out.println(list); } public static boolean myContains(String[] arr, String key) { for (int i = 0; i < arr.length; i++) { if (arr[i].equals(key)) return true; } return false; } // toString的经典实现 public static String myToString(int[] a) { int iMax = a.length - 1; if (iMax == -1) return "[]"; StringBuilder b = new StringBuilder(); b.append('['); for (int i = 0;; i++) {// 中间省略条件判断,提高效率 b.append(a[i]); if (i == iMax) return b.append(']').toString(); b.append(", "); } } }
集合转成数组
使用的是Collection接口中的toArray方法。
集合转成数组,可以对集合中的元素操作的方法进行限定,不允许对其进行增删。
toArray方法需要传入一个指定类型的数组
长度的定义方法:
如果长度小于集合的size,那么该方法会创建一个同类型并和集合相同size的数组;
如果长度大于集合的size,该方法就会使用指定的数组村粗集合中的元素,其他位置默
为null;
建议数组长度是指定的结合的size
package cn.itcast.p3.toolclass.arrays.demo; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ToArray { /** * @param args */ public static void main(String[] args) { /* * 集合转成数组 */ List<String> list=new ArrayList<String>(); list.add("abc1"); list.add("abc2"); list.add("abc3"); /* * toArray方法需要传入一个指定类型的数组 * 长度的定义方法: * 如果长度小于集合的size,那么该方法会创建一个同类型并和集合相同size的数组; * 如果长度大于集合的size,该方法就会使用指定的数组村粗集合中的元素,其他位置默认为null; * 建议数组长度是指定的结合的size */ String[] arr=list.toArray(new String[2]); System.out.println(Arrays.toString(arr)); } }
foreach循环
格式:
for(类型 变量 : Collection集合 | 数组)
{
}
传统for循环和高级for的区别:
传统for可以完成对语句执行多次,因为可以定义控制循环的增量和条件;
而高级for是只用简化形式,它必须有被遍历的目标,该目标要么是数组,要么是Collection集合;
对于数组的遍历,如果仅仅是获取数组中的元素,可以使用高级for;如果要对数组的脚标进行操作,建议使用传统for。
package cn.itcast.p4.news.demo; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class ForEachDemo { /** * @param args */ public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("abc1"); list.add("abc2"); list.add("abc3"); for (String s : list) {// 简化书写 System.out.println(s); } int[] arr = { 3, 1, 5, 6, 7, 2 }; for (int i : arr) { System.out.println(i); } // 可以使用高级for遍历map集合:不能直接作用,但是可以将map转成单列的set,就可以使用 Map<Integer,String> map=new HashMap<Integer,String>(); map.put(3, "zhagsan"); map.put(1, "wangyi"); map.put(7, "wangwu"); map.put(4, "zhangsan"); for(Integer key:map.keySet()){ String value=map.get(key); System.out.println(key+":"+value); } for(Map.Entry<Integer, String> me:map.entrySet()){ Integer key=me.getKey(); String value=me.getValue(); System.out.println(key+":"+value); } // Iterator<String> it=list.iterator(); // while(it.hasNext()){ // System.out.println(it.next()); // } } }
函数可变参数
其实就是一个数组,但是接受的是数组中的元素,自动将这些元素封装成数组,简化了调用者的书写。
※注意事项:可变参数类型,必须定义在参数列表的结尾。
package cn.itcast.p4.news.demo; public class ParamterDemo { public static void main(String[] args) { int[] arr = { 5, 1, 4, 7, 3 }; int sum1 = add(arr); System.out.println("sum1=" + sum1); int sum2 = newAdd(5, 1, 4, 7, 3); System.out.println("sum2=" + sum2); int sum3 = newAdd(5, 1, 2, 7, 9, 8, 7, 6); System.out.println("sum3=" + sum3); } public static int newAdd(int a,int... arr) {// 可变参数 int sum = 0; for (int i = 0; i < arr.length; i++) { sum += arr[i]; } return sum; } public static int add(int[] arr) { int sum = 0; for (int i = 0; i < arr.length; i++) { sum += arr[i]; } return sum; } }
静态导入
package cn.itcast.p4.news.demo; //import static java.util.Collections.sort;//其实导入的是类中的静态成员 //import static java.util.Collections.max; import static java.lang.System.out; import static java.util.Collections.max; import static java.util.Collections.sort; import java.util.ArrayList; import java.util.List; public class StaticImportDemo { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("abc1"); list.add("abc2"); list.add("abc3"); out.println(list); // Collections.sort(list); sort(list); out.println(list); // String max = Collections.max(list); String max = max(list); out.println("max=" + max); } }
其他对象API
System类
public final class Systemextends Object
System 类包含一些有用的类字段和方法。它不能被实例化。
System类中的方法和属性都是静态的。
static long currentTimeMillis(); //返回以毫秒为单位的当前时间。
static String getProperty(String key, String def)
获取用指定键描述的系统属性。
Object setProperty(String key, String value)
调用 Hashtable 的方法 put。
package cn.itcast.p1.otherapi.demo; import java.util.Properties; import java.util.Set; public class SystemDemo { private static final String SPACE_SEPARATOR = System .getProperty("line.separator"); /** * @param args */ public static void main(String[] args) { System.out.println("Hello" + SPACE_SEPARATOR + " World");// 能实现任何系统中的换行 // demo_0(); // demo_1(); //给系统设置属性信息,这些信息是全局的,其他程序都可以使用 System.setProperty("myclasspath", "c:\\myclass"); } public static void demo_1() { // 获取系统的徐行信息,并存储到了Properties集合中 /* * Properties集合中存储的都是String类型的键和值 最好使用它自己的存储和取出的方法来完成元素的操作 */ Properties prop = System.getProperties(); Set<String> nameSet = prop.stringPropertyNames(); for (String name : nameSet) { String value = prop.getProperty(name); System.out.println(name + "::" + value); } } private static void demo_0() { long l1 = System.currentTimeMillis(); System.out.println(l1); // System.out.println(l1/1000/60/60/24/365); long temp = 1344227567838l; long l2 = System.currentTimeMillis(); System.out.println(l2 - temp); } }
public class Runtimeextends
Object每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。可以通过 getRuntime 方法获取当前运行时。
应用程序不能创建自己的 Runtime 类实例。
Runtime没有构建方法摘要,说明该类不能创建对象。
又发现,Runtime有非静态的方法,说明该类应该提供静态的返回该类对象的方法。
而且只有一个,说明Runtime类使用了单例设计模式完成。※
package cn.itcast.p1.otherapi.demo; import java.io.IOException; public class RuntimeDemo { /** * @param args * @throws IOException * @throws InterruptedException */ public static void main(String[] args) throws IOException, InterruptedException { Runtime r=Runtime.getRuntime(); Process p=r.exec("notepad.exe"); Thread.sleep(5000); p.destroy(); } }
Math
public final class Mathextends ObjectMath
类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。
常用的方法:
ceil();//返回大于参数的最小整数
floor();//返回小于参数的最大整数
round();//返回四舍五入后的整数
pow(a,b);//返回a的b次方
random();
//返回带正号的 double 值,该值大于等于 0.0 且小于 1.0。返回值是一个伪随机选择的数,在该范围内(近似)均匀分布。
package cn.itcast.p1.otherapi.demo; import java.util.Random; public class MathDemo { /** * @param args */ public static void main(String[] args) { // double d1 = Math.ceil(12.56); // double d2 = Math.floor(12.56); // double d3 = Math.round(12.56); // // System.out.println("d1=" + d1); // System.out.println("d2=" + d2); // System.out.println("d3=" + d3); // // double d = Math.pow(10, 2); // System.out.println("d=" + d); Random r = new Random(); for (int i = 0; i < 10; i++) { // double d = Math.ceil(Math.random()*100); // double d = (int) (r.nextDouble() * 6 + 1); int d = r.nextInt(6) + 1; System.out.println(d); } } }
Date类
public class Dateextends Objectimplements Serializable, Cloneable, Comparable<Date>
年份 y 由整数 y - 1900 表示。
月份由从 0 至 11 的整数表示;0 是一月、1 是二月等等;因此 11 是十二月。
日期(一月中的某天)按通常方式由整数 1 至 31 表示。
小时由从 0 至 23 的整数表示。因此,从午夜到 1 a.m. 的时间是 0 点,从中午到 1 p.m. 的时间是 12 点。
分钟按通常方式由 0 至 59 的整数表示。
秒由 0 至 61 的整数表示;值 60 和 61 只对闰秒发生,尽管那样,也只用在实际正确跟踪闰秒的 Java 实现中。于按当前引入闰秒的方式,两个闰秒在同一分钟内发生是极不可能的,但此规范遵循 ISO C 的日期和时间约定。
日期对象和毫秒值之间的转换
毫秒值-->日期对象:
1.通过Date对象的构造方法完成 new Date(timeMilis);
2.通过setTime()设置;
目的:可以通过Date对象的方法对该日期中的各个字段(年月日等)进行操作;
日期对象-->毫秒值
getTime();
目的:可以通过具体的数值进行运算;
boolean after(Date when)
测试此日期是否在指定日期之后。
boolean before(Date when)
测试此日期是否在指定日期之前。
boolean equals(Object obj)
比较两个日期的相等性。
int compareTo(Date anotherDate)
比较两个日期的顺序。
String toString()
把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。
对日期对象进行格式化
static DateFormat getDateTimeInstance(int dateStyle, int timeStyle)
获取日期/时间格式器,该格式器具有默认语言环境的给定日期和时间格式化风格。
package cn.itcast.p1.otherapi; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class DateDemo { /** * @param args * @throws ParseException */ public static void main(String[] args) throws ParseException { // methodDemo_1(); // methodDemo_2(); methodDemo_3(); } /** * 日期格式的字符串-->日期对象,使用的是DateFormat类中的parse方法 * @throws ParseException */ public static void methodDemo_3() throws ParseException { String str_date = "2012年4月19日"; str_date = "2011---8---17"; DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG); // 只能解析默认风格的日期,如2012-8-17 // DateFormat dateFormat = DateFormat.getDateInstance();// dateFormat = new SimpleDateFormat("yyyy---MM---dd");// 自定义风格 Date d = dateFormat.parse(str_date); System.out.println(d); } /** * 对日期对象进行格式化 日期对象-->日期格式的字符串,使用的是DateFormat类中的format方法 */ public static void methodDemo_2() { Date date = new Date(); // 获取日期格式对向,具备着默认风格。FULL、LONG等可以指定风格 DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL); dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG); // 如果风格是自定义的,如何解决 dateFormat = new SimpleDateFormat("yyyy--MM--dd"); String str_date = dateFormat.format(date); System.out.println(str_date); } private static void methodDemo_1() { long time = System.currentTimeMillis(); System.out.println(time);// 1344324000837 Date date = new Date();// 将当前日期和时间封装成对象 System.out.println(date);// Tue Aug 07 15:17:40 CST 2012 Date date2 = new Date(1344324000837l);// 将制定毫秒值封装成对象 System.out.println(date2); } }
Date练习示例:
package cn.itcast.p1.otherapi.test; import java.text.DateFormat; import java.text.ParseException; import java.util.Date; /* * "2012-3-17"到"2012-4-6" * 中间有多少天 * 思路: * 两个日期相减。 * 必须要有两个可以进行减法运算的数。 * 能相减的可以是毫秒值。使用Date对象获取毫秒值。 * 从日期格式字符串获取时间。将字符串转成Date对象。 * * 1.将日期格式的字符串转成对象; * 2.将Date对象转成毫秒值; * 3.毫秒值相减,然后转换成天数。 */ public class DateTest { /** * @param args * @throws ParseException */ public static void main(String[] args) throws ParseException { String str_date1 = "2012-3-17"; String str_date2 = "2012-4-6"; test(str_date1, str_date2); } public static void test(String str_date1, String str_date2) throws ParseException { // 1.将日期字符串转成日期对象 // 定义日期格式对象 DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT); // dateFormat=new SimpleDateFormat("yyyy-MM-dd"); //2.将Date对象转换成毫秒值 Date date1 = dateFormat.parse(str_date1); Date date2 = dateFormat.parse(str_date2); long time1 = date1.getTime(); long time2 = date2.getTime(); //3.毫秒值相减,然后转换成天数 long time = Math.abs(time1 - time2); int day = getDay(time); System.out.println(day); } public static int getDay(long time) { return (int) (time / 1000 / 60 / 60 / 24); } }
Calendar类
package cn.itcast.p1.otherapi; import java.util.Calendar; public class CalendarDemo { /** * @param args */ public static void main(String[] args) { Calendar c = Calendar.getInstance(); int year = 2012; showDays(year); } /** * @param c */ private static void showDays(int year) { Calendar c = Calendar.getInstance(); c.set(year, 2, 1); c.add(Calendar.DAY_OF_MONTH, -1); showDate(c); } /** * Calendar c = Calendar.getInstance(); */ private static void showDate(Calendar c) { int year = c.get(Calendar.YEAR); int month = c.get(Calendar.MONTH) + 1; int day = c.get(Calendar.DAY_OF_MONTH); int week = c.get(Calendar.DAY_OF_WEEK); System.out.println(year + "年" + month + "月" + day + "日 " + getWeek(week)); } public static String getWeek(int i) { String[] weeks = { "", "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" }; return weeks[i]; } }