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];
    }

}

posted on 2012-08-07 18:37  foolchen  阅读(598)  评论(0编辑  收藏  举报

导航