Java集合框架总结

1. 集合和数组的区别?

  1. 最大区别在于数组是固定长度的(即在内存中一定连续),静态存储结构,而集合是可变的长度,而这个特点让集合具有更高的实用性,比如程序运行不知道究竟需要多少对象,需要在空间不足时自动扩增容量,大大提高了存储资源的高效使用。
  2. 数组可以存储基本数据类型和引用数据类型,而集合存在的就是专门用来存储对象的,所以就存储对象,集合可以存储不同类型的对象,而数组只能存储一种类型对象。
  3. 所以当我们专门存储和操作对象时,首选集合,当需要存储基本数据类型时就考虑数组了。

2.集合体系是什么?

这里写图片描述

Collection
|--List:元素是有序的,元素可以重复。因为该集合体系有索引。
    |--ArrayList:底层的数据结构使用的是数组结构。特点是查询数据快,但增删稍慢。线程不同步
    |--LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。
    |--Vector:底层是数组数据结构,线程同步,被ArrayList替代了,因为效率低。
|--Set:元素是无序,(存入和取出的顺序不一定一致),元素不可以重复。Set集合的功能和Collection是一致的。
    |--HashSet:数据结构是哈希表。线程是非同步的。
    保证元素唯一性的原理:判断元素的hashCode值是否相同。
    如果相同,还会继续判断元素的equals方法,是否为true。
    |--TreeSet:可以对Set集合中的元素进行排序。
    底层数据结构是二叉树。
    保证元素唯一性的依据:
    compareTo方法return 0.

    TreeSet排序的第一种方式:让元素自身具备比较性。
    元素需要实现Comparable接口,覆盖compareTo方法。
    也种方式也成为元素的自然顺序,或者叫做默认顺序。

    TreeSet的第二种排序方式。
    当元素自身不具备比较性时,或者具备的比较性不是所需要的。
    这时就需要让集合自身具备比较性,即实现Comparator接口作为对象传递到集合,复写compare方法。
    在集合初始化时,就有了比较方式。
Map
|--Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。jdk    1.0.效率低。
|--HashMap:底层是哈希表数据结构,允许使用 null 值和 null 键,该集合是不同步的。将    hashtable替代,jdk1.2.效率高。
|--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。

3.迭代器

集合作为存储的容器,既然是容器,那么他的作用必然方便取出其中的数据。所以就产生了迭代器,类似与数组的遍历,迭代器是专门针对集合的遍历。
迭代器实现原理:集合有着不同的容器,虽然这些容器的数据结构不同,但是都有共性的内容,判读和取出,我们将这些共性抽取,在实现中写不同的动作细节,并把它放到集合的内部类中,提供对外的方法iterator()。
有两种写的形式,如下:

        Iterator it=a1.iterator();
        while(it.hasNext())
        {
            sop(it.next());
        }


        for(Iterator it=a1.iterator();it.hasNext();)
        {
            sop(it.next());
        }

4.比较器
TreeSet,TreeMap排序两种方式

一、自然排序(元素具备比较性) 实现Comparable接口

二、比较器排序(集合具备比较性) 实现Comparator接口

import java.util.*;

class TreeSetDemo
{
    public static void main(String[] args)
    {
        //传递比较器对象
        TreeSet ts=new TreeSet(new MyCompare());
        ts.add(new Student("lisi02",23));
        ts.add(new Student("lisi06",22));
        ts.add(new Student("lisi09",29));
        ts.add(new Student("lisi06",21));


        Iterator it=ts.iterator();
        while(it.hasNext())
        {
            Student stu=(Student)it.next();
            System.out.println(stu.getName()+"::"+stu.getAge());
        }
    }
}
//让元素自身具备比较性,重写compareTo方法
class Student implements Comparable//该接口强制让学生实现
{
    private String name;
    private int age;
    Student(String name,int age)
    {
        this.name=name;
        this.age=age;
    }
    public String getName()
    {
        return name;
    }
    public int getAge()
    {
        return age;
    }
    public int compareTo(Object obj)
    {
        //return 0;

        if(!(obj instanceof Student))
            throw new RuntimeException("不是学生对象");
        Student s=(Student)obj;
        System.out.println(this.name+".....compareto......"+s.name);
        if(this.age>s.age)
            return 1;
        if(this.age==s.age)
        {
            return this.name.compareTo(s.name);
        }
        return -1;

    }
}
//定义一个类,实现Comparator接口,覆盖compare方法。
class MyCompare implements Comparator
{
    public int compare(Object o1,Object o2)
    {
        Student s1=(Student)o1;
        Student s2=(Student)o2;

        //return s1.getName().compareTo(s2.getName());

        int num=s1.getName().compareTo(s2.getName());
        if(num==0)
        {

            return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
        }
        return num;

    }
}

5.集合那么多什么时候该用谁?
第一,判断是否是键值对
第二,判断是否需要排序
第三,判断是否唯一
第四,判断是否安全或高效率

/*
练习:
"sdfefjijntueojfiefj"获取该字符串中的字母出现的次数。
希望打印结果:a(1)c(2).....

通过结果发现,每一个字母都有对应的次数。
说明字母和次数之间都有映射关系。

注意了,当发现有映射关系时,可以选择map集合。
因为map集合中存放就是映射关系。

什么使用map集合呢?
当数据之间存在这映射关系时,就要先想map集合。

思路:
1,将字符串转换成字符数组。因为要对每一个字母进行操作。

2,定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。

3,遍历字符数组。
    将每一个字母作为键去查map集合。
    如果返回null,将该字母和1存入到map集合中。
    如果返回不是null,说明该字母在map集合已经存在并有对应次数。
    那么就获取该次数并进行自增。,然后将该字母和自增后的次数存入到map集合中。覆盖调用原理键所对应的值。

4,将map集合中的数据变成指定的字符串形式返回。


*/
import java.util.*;
class MapTest3 
{
    public static void main(String[] args) 
    {
        String s=charCount("aabbc2--===cdd`aerfefer");
        System.out.println(s);
    }
    //传入一个字符串,返回一个a=1,c=2....的字符串
    public static String charCount(String str)
    {
        char[] chs=str.toCharArray();

        TreeMap<Character,Integer> tm=new TreeMap<Character,Integer>();
        int count = 0;
        for(int x=0;x<chs.length;x++)
        {
            if(!(chs[x]>='a' && chs[x]<='z' || chs[x]>='Z' && chs[x]<='Z'))
                continue;
            Integer value=tm.get(chs[x]);

            if(value!=null)
                count = value;
            count++;
            tm.put(chs[x],count);//直接往集合中存储字符和数字,为什么可以,因为自动装箱。
            count = 0;
            /*
            if(value==null)
                tm.put(chs[x],1);
            else
            {
                value=value+1;
                tm.put(chs[x],value);//覆盖原来的1,当key相同时。
            }
            */
        }
        //System.out.println(tm);
        //将集合取出来,按照指定形式存入StringBuffer中
        StringBuffer sb=new StringBuffer();
        Set<Map.Entry<Character,Integer>> entrySet=tm.entrySet();
        Iterator<Map.Entry<Character,Integer>> it=entrySet.iterator();
        while(it.hasNext())
        {
            Map.Entry<Character,Integer> me=it.next();
            Character ch=me.getKey();
            Integer value=me.getValue();
            sb.append(ch+"("+value+")");
        }

        return sb.toString();


    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值