黑马程序员——java基础——集合(二)

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——

泛型:JDK1.5版本以后出现新特性。用于解决安全问题,是一个类型安全机制。

泛型好处:
1.将运行时的异常转换到了编译时期,以便于程序员处理
2.避免了强转的麻烦
用<>来操作引用数据类型

什么时候定义泛型呢?
1.在集合中较为常见
2.只要见到<>就要定义泛型

当使用集合时,将集合中储存的数据类型作为参数传递给<>即可

泛型定义在类上时,若类中的方法使用该泛型,那么在类建立对象后该方法能操作的引用数据类型就确定了。
泛型定义在方法上时,放在void的前面,并且可以操作多种引用数据类型
静态方法的泛型只能定义在方法上,因为静态优先于对象而存在。

class Demo<T>
{
    public void show(T t)
    {
        System.out.println("show"+t);   
    }
    public <W> void function(W w)
    {
        System.out.println("function"+w);
    }
    public static <M> void method(M m)
    {
        System.out.println("method"+m);
    }
}

interface Inter<T>//泛型定义在接口上
{
    void show(T t);
}

class Demo2 implements Inter<String>//Demo2后可以不用写泛型,因为泛型已经确定
{
    public void show(String s)
    {
        System.out.println("show2....."+s);
    }
}

class Demo3<T> implements Inter<T>//泛型的引用数据类型不确定时,Demo3后一定要加泛型
{
    public void show(T t)
    {
        System.out.println("show3...."+t);
    }
}
class GenericDemo
{
    public static void main(String[] args) 
    {
        Demo2 d = new Demo2();
        d.show("jujuju");

        Demo3<Integer> d3 = new Demo3<Integer>();
        d3.show(4);

        Demo<String> d = new Demo<String>();
        d.show("haha");
        //d.show(2);//编译会失败,因为show方法所传入的数据类型已经确定,为String
        d.function("heiehie");
        d.function(3);
        //Demo<String>.method("heheheh");//调用时不能带泛型,会编译失败
        Demo.method(4);
    }
}

Map集合:
Map
Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。jdk1.0.效率低。
HashMap:底层是哈希表数据结构,允许使用 null 值和 null 键,该集合是不同步的。将hashtable替代,jdk1.2.效率高。
TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。他和TreeSet集合一样,有两种方法给集合中的元素排序,一般会按照键排序。

Map集合和Set集合很像。其实Set集合底层就是使用了Map集合。

Map集合没有迭代器,取出Map集合中的键和值的两种方法
第一种方法:
1.通过调用keySet方法会将所有的键存储到Set集合中,在通过Set集合的迭代器取出键
2.通过Map集合的get方法可以取出值

第二种方法:
1.通过调用entrySet方法会将键和值的关系存储到Set集合中,再通过Set集合的迭代器取出他们的映射关系
2.他们的映射关系是一个接口,通过调用该接口的getKey()和getValue()方法可以取出键和值

定义一个学生的类有姓名,年龄
每个学生都有地址
认为姓名和年龄相同的学生为同一个人,要求保证学生的唯一性
思路:
1.描述学生
2.用一个集合将学生存储
3.取出元素

import java.util.*;
class Student implements Comparable<Student>
{
    private String name ;
    private int age;
    Student(String name,int age)
    {
        this.name = name ;
        this.age = age;
    }
    //覆盖hashCode方法,保证对象的唯一性
    public int hashCode()
    {
        return this.name.hashCode()+age*12;
    }
    //覆盖equals方法,让其按照指定的方式比较
    public boolean equals(Object obj)
    {
        if(!(obj instanceof Student))
            throw new RuntimeException();
        Student s = (Student)obj;
        return this.name.equals(s.name) && this.age==s.age;
    }
    public int compareTo(Student s)
    {
        int num = this.name.compareTo(s.name);
        if(num==0)
            return new Integer(this.age).compareTo(new Integer(s.age));
        return num;
    }
    public void setName(String name)
    {
        this.name = name ;
    }
    public String getName()
    {
        return name;
    }
    public void setAge(int age)
    {
        this.age = age;
    }
    public int getAge()
    {
        return age;
    }
    public String toString()
    {
        return name+"-----"+age;
    }
}
class HashMapTest
{
    public static void main(String[] args) 
    {
        HashMap<Student,String> hm = new HashMap<Student,String>();

        hm.put(new Student("lishi01",21),"beijing");
        hm.put(new Student("lishi02",25),"shanghai");
        hm.put(new Student("lishi01",21),"nanjin");
        hm.put(new Student("lishi01",21),"beijing");
        hm.put(new Student("lishi05",18),"tianjin");

        //取出Map集合中的元素:第二种方法,将键和值的关系存储到Set集合中
        Set<Map.Entry<Student,String>> entry = hm.entrySet();
        //调用Set集合中的迭代器
        Iterator<Map.Entry<Student,String>> ite = entry.iterator();
        while (ite.hasNext())
        {
            Map.Entry<Student,String> me = ite.next();
            Student stu = me.getKey();
            String str = me.getValue();
            System.out.println(stu.toString()+"...|||..."+str);
        }

        //取出Map集合中的元素:第一种方法,将所有的键存储到Set集合中
        Set<Student> key = hm.keySet();
        //调用Set集合中的迭代器
        Iterator<Student> it = key.iterator();
        while (it.hasNext())
        {
            Student s = it.next();
            String value = hm.get(s);
            System.out.println(s+"......."+value);
        }
    }
}

Map集合的应用:
给一个字符串”adaddecgg”要求将每个字符出现的次数打印
打印方式为a(2)c(1)d(3)……..
分析:
在将字符串遍历的过程中,将字符作为键,次数作为值存到集合中
然后在将集合中的元素按照规定的方式打印
步骤:
1.将字符串转为字符数组
2.定义一个具有键值的集合,因为需要排序所以选择TreeMap集合
3.遍历数组中的元素,并将字符作为键,次数作为值存入到集合中
存入时需要判断,按照键取出其对应的值,若值为null,则将字符和1存入
若值不为null,则将值取出并自增后在和字符一起存入
4.遍历集合,若要集合中的元素按照规定的方法打印,可以将键和值存入到一个容器后在取出

import java.util.*;
class MapTest 
{
    public static void main(String[] args) 
    {
        String s = getCount("aabdecb++--saadde");
        System.out.println(s);
    }
    public static String getCount(String str)
    {
        char[] cha = str.toCharArray();

        TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();

        int count = 0 ;
        for (int x=0;x<cha.length ;x++ )
        {
            Integer value = tm.get(cha[x]);

            if(!(cha[x]>='a' && cha[x]<='z' || cha[x]>='A' && cha[x]<='Z'))
                continue ;//若不在这个范围就直接让本次循环结束,然后进行下一次的循环

            if (value!=null)
                count = value;//判断value有没有值,若有则用count记录后然后自增,若没有就不会记录,直接自增一次

            count++;
            //将字符作为键,出现的次数作为值存入TreeMap集合
            tm.put(cha[x],count);

            count = 0 ;//因为count定义在成员位置上,会累加,所以每次用完后需要清零
            /*
            if(value==null)
            {
                tm.put(cha[x],1);
            }
            else
            {
                value++;
                tm.put(cha[x],value);
            }
            */
        }
        //定义一个容器用来将集合中取出的键和值以指定的形式存入,然后返回
        StringBuilder sb = new StringBuilder();
        Set<Character> key = tm.keySet();
        Iterator<Character> it = key.iterator();
        while (it.hasNext())
        {
            Character key1 = it.next();//用char接收也可以
            Integer value = tm.get(key1);//用int接收也可以
            //System.out.print(key1+"("+value+")");
            sb.append(key1+"("+value+")");
        }
        return sb.toString();
    }
}

集合框架的工具类。
Collections:集合框架的工具类。里面定义的都是静态方法。

Collections和Collection的区别:
Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。
它有两个常用的子接口,
List:对元素都有定义索引。有序的。可以重复元素。
Set:不可以重复元素。无序。
Collections是集合框架中的一个工具类。该类中的方法都是静态的
提供的方法中有可以对list集合进行排序,二分查找,替换反转,加锁等。
通常常用的集合都是线程不安全的。因为要提高效率。如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。

Arrays:用于操作数组的工具类。里面都是静态方法,它提供了很多对数组进行操作的方法(查阅API文档)。
asList:将数组变成list集合。
把数组变成list集合有什么好处?
可以使用集合的思想和方法来操作数组中的元素。
注意:将数组变成集合,不可以使用集合的增删方法。因为数组的长度是固定。
如果增删。那么会反生UnsupportedOperationException
如果数组中的元素都是对象。那么变成集合时,数组中的元素就直接转成集合中的元素。如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。

集合变数组。
Collection接口中的toArray方法。
T[] toArray(T[] a)
如 String[] arr = 集合对象.toArray(new String[集合对象.size()]);
为什么要将集合变数组?
为了限定对元素的操作,不需要进行增删了。

高级for循环
格式:
for(数据类型 变量名 : 被遍历的集合(Collection)或者数组)
{

}
对集合进行遍历。
只能获取集合元素。但是不能对集合进行操作。

import java.util.*;
class ForDemo 
{
    public static void main(String[] args) 
    {
        ArrayList<String> al = new ArrayList<String>();

        al.add("abc1");
        al.add("abc2");
        al.add("abc3");

        for(String s : al)
        {
            System.out.println(s);
        }

        int[] arr = {3,5,1};
        for(int x=0; x<arr.length; x++)
        {
            System.out.println(arr[x]);
        }
        for(int i : arr)
        {
            System.out.println("i:"+i);
        }

        HashMap<Integer,String> hm = new HashMap<Integer,String>();
        hm.put(1,"a");
        hm.put(2,"b");
        hm.put(3,"c");

        Set<Integer> keySet = hm.keySet();
        for(Integer i : keySet)
        {
            System.out.println(i+"::"+hm.get(i));
        }

//      Set<Map.Entry<Integer,String>> entrySet = hm.entrySet();
//      for(Map.Entry<Integer,String> me : entrySet)

        for(Map.Entry<Integer,String> me : hm.entrySet())
        {
            System.out.println(me.getKey()+"------"+me.getValue());
        }
    }
}

方法的可变参数。
在使用时注意:可变参数一定要定义在参数列表最后面。
可变参数:可以理解为将这些参数封装成了相对应的数组后传入。
其实就是数组参数的简写形式。不用每一次都手动的建立数组对象。只要将要操作的元素作为参数传递即可,隐式将这些参数封装成了数组。

class ParamMethodDemo
{
    public static void main(String[] args) 
    {
        show("haha",2,3,4,5,6);
    }
    public static void show(String str,int... arr)
    {
        System.out.println(str+"....."+arr.length);
    }
}

import static 静态导入,导入类中所有的静态成员。
当类名重名时,需要指定具体的包名。
当方法重名时,指定具体所属的对象或者类。

需要理解和掌握的一些其他对象
System类 获取和更改系统的属性信息,有可以和流相结合的一些方法。
Properties类 是Map集合,键值都是String,可以与流相结合
Runtime类 getRuntime方法 exec方法等

Date类 DateFormat类 Calendar类 对时间进行操作
Date d = new Date();
将模式封装到SimpleDateformat对象中。
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy年MM月dd日E hh:mm:ss”);
调用format方法让模式格式化指定Date对象。
String time = sdf.format(d);

Math类 包含用于执行基本数学运算的方法

public static void mehthod()
{
    for (int x=0;x<10 ;x++ )
    {
        Random r = new Random();
        int d = r.nextInt(10)+1;
        //int d = (int)(Math.random()*10+1);//伪随机数
    }
    double d = Math.ceil(-12.56);//返回大于指定数的最小整数
    double d1 = Math.floor(-12.56);//返回小于指定数的最大整数
    long l = Math.round(-12.22);//四舍五入
    double d2 = Math.pow(3,2);//3^2
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值