[JAVA基础]集合

一、集合概述

由于数组长度固定,且不能存储对象,所以JAVA出现了集合来存储对象的引用。

 

JAVA集合继承关系

 

 

数据结构知识:

逻辑结构:无序集合 线性结构 树 图

线性表的物理存储:

链式存储(单链表,循环链表,双链表,双循环链表)增删 O(1) 查找O(lgN)

顺序存储(数组)  增删O(N) 查找O(1)

 

手写单链表

 

Collection共性方法:

ArrayList al = new ArrayList();

al.add();        //添加元素

al.size();   //获取集合长度

al.remove(); //删除元素  

al.clear();  //清空集合

al.contains(); //是否包含某个元素

al.isEmpty(); //集合是否为空

al1.retainAll(al2);  //取a1和a2的交集

al.removeAll(al2)  //去a1和a2的交集

 

二、List  //(有序,元素可重复)  元素判断用equals()方法

 

 List

  |--ArrayList   底层数据结构为数组,有索引,查询修改速度快,增删较慢,常用。

  |--LinkedList   底层数据结构为链表,无索引,增删速度快,查询慢。

       |--Vector             底层数据结构为数组,有索引。已被ArrayList替代。同步,长度不可变。

 

常见方法:

add(index,elements);  //在指定索引处添加元素

remove(index);  //   删除索引处的元素

set(index,element)  //;  设置索引处的元素

get(index);   //   获取索引处的元素

subList(int from,int to Index);  //获取子集,包含头,不包含尾巴

ListIterator(); //List集合特有迭代器,包含特有方法:hasPrevious();pervious();

Iterator是一个接口,在集合的内部,有一个类实现了Iterator接口,以内部类的形式对集合内部元素进行存取操作,好比抓娃娃机的爪子。

Enumeration en = v.Elements;for(en.hasMoreElements ; en.nextElements ; )

 

程序举例:

1.去重ArrayList中的重复元素  ArrayList

 

package com.fan.testmain;

import java.util.ArrayList;
import java.util.Iterator;


public class Test3 {


        public static void main(String[] args) {
            
            ArrayList al = new ArrayList();
            
            al.add("孙悟空");al.add("如来佛");
            al.add("观音菩萨");al.add("如来佛");
            
            printArrayList(al);
            
            printArrayList(elementUnique(al));
            
            
            
            
        }
        
        
        
        public static ArrayList elementUnique(ArrayList al1) {  //封装去重元素方法
            
            
            ArrayList al2 = new ArrayList();   //建立信的集合接收去重后的元素
            
            for(Iterator it = al1.iterator();it.hasNext() ; ){  //遍历
                
                Object obj = it.next();
                if(! al2.contains(obj))    //取出al1中的所有元素,放入新集合中,如果元素存在,则不存
                    al2.add(obj);
            }
                
            return al2;    
            
            
        }
        
        public static void printArrayList(ArrayList al) {  //打印集合元素方法
            
            Iterator it = al.iterator();
            
            while(it.hasNext()) {
                
                System.out.println(it.next());
            }
        }
    
}

 

 

 

2.模仿队列     LinkedList  调用removeFirst()和addLast()方法

 

package com.fan.testmain;


import java.util.Iterator;
import java.util.LinkedList;


public class Test3 {


        public static void main(String[] args) {
            
            DuiLie dl = new DuiLie();  
            
            dl.add(1);    //模拟进入队列
            dl.add(2);
            dl.add(3);
            dl.add(4);
            dl.add(5);
            dl.add(6);
            
            while(!dl.isEmpty()) {   //模拟离开队列
                
                System.out.println(dl.remove());
            }
            
            
            
        }
        
        
        
    
    
}

class DuiLie {
    
    
    private LinkedList list;
    
    DuiLie() {
        
        this.list = new LinkedList();
    }
    
    public void add(Object obj) {
        
        list.add(obj);
    }
    
    public Object remove() {
        
        return list.removeFirst();
    }
    
    public boolean isEmpty() {
        
        return list.isEmpty();
    }
}

 

三、Set  元素不可重复 

 |--HashSet:底层数据结构是哈希表。线程不同步。 保证元素唯一性的原理:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals方法,是否为true。

 |--TreeSet:可以对Set集合中的元素进行排序。默认按照字母的自然排序。底层数据结构是二叉树。保证元素唯一性的依据:compareTo方法return 0。

 

 HashSet

 hashCode和equals来完成保证元素唯一性。如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashCode值不同,不会调用equals。

示例

class Person
{
    private String name;
    private int age;

    Person(String name,int age)
    {
        this.name=name;
        this.age=age;
    }

    public String getName()
    {
        return name;
    }

    public int getAge()
    {
        return age;
    }

    public boolean equals(Object obj)
    {
        if(!(obj instanceof Person))
            return false;
        Person p=(Person)obj;
        return this.name.equals(p.name)&&this.age==p.age;
    }

    public int hashCode()
    {
        return this.name.hashCode()+this.age;
    }
}
class  HashSetTest
{
    public static void main(String[] args) 
    {
        HashSet h=new HashSet();
        h.add(new Person("shenm",10));
        h.add(new Person("shenm2",6));
        h.add(new Person("shenm1",30));
        h.add(new Person("shenm0",10));
        h.add(new Person("shenm0",10));
        
        getOut(h);

    }

    //取出元素
    public static void getOut(HashSet h)
    {
        for (Iterator it=h.iterator(); it.hasNext(); )
        {
            Person p=(Person)it.next();
            sop(p.getName()+"..."+p.getAge());
        }
    }

    //打印
    public static void sop(Object obj)
    {
        System.out.println(obj);
    }
}

TreeSet

TreeSet集合底层数据结构为二叉树,元素不可以重复,结合内元素有序(有序即是根据存储元素的大小进行排序,这就需要元素具备比较性,Comparable和Comparator)

程序举例

1、Comparable和Comparator两种方式

 

import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.TreeSet;

/*TreeSet的元素比较
 * 
 */
public class Test3 {


        public static void main(String[] args) {
            
            
            TreeSet<Person> ts1 = new TreeSet<Person>();    //实现Comparable的方式
            ts1.add(new Person("张三",19));
            ts1.add(new Person("张三",18));
            ts1.add(new Person("张四",18));
            ts1.add(new Person("王五",18));
            printTs(ts1);
            
            TreeSet<Person> ts2 = new TreeSet<Person>(new MyComp());    //比较器
            ts2.add(new Person("alice",19));
            ts2.add(new Person("alice",18));
            ts2.add(new Person("edison",20));
            ts2.add(new Person("edison",18));
            printTs(ts2);
            
        }
        
        
        public static void printTs(TreeSet ts) {
            
            
            
            
            for(Iterator it = ts.iterator();it.hasNext() ; ) {
                System.out.println(it.next());
            }
                
        }
    
    
}

class Person implements Comparable {   //创建Person类实现Comparable接口,实现具备比较性
    
    private String name ;
    private int age;
    
    Person(String name, int age) {
        
        this.age = age;
        this.name = name;
    }
    
    public int getAge() {
        return this.age;
    }
    
    public String getName() {
        return this.name;
    }
    
    public int compareTo(Object obj) {   //overide compareTo()
        
        if(!(obj instanceof Person))
                
            throw new RuntimeException("类型不匹配无法比较");
        Person p1 = (Person)obj;
        
        int i = this.name.compareTo(p1.name);
        
        if(i == 0) 
            return this.age - p1.age;
        return i ;
    }
        
    public String toString() {
        return this.name + "-----" +this.age;
    }
    
}



class MyComp implements Comparator {   //自定义实现Comparator接口的类,作为TreeSet(Comparator c)的参数

    @Override
    public int compare(Object obj1, Object obj2) {
        // TODO Auto-generated method stub
        
        Person p1 = (Person)obj1;
        Person p2 = (Person)obj2;
        
        int i = p2.getName().compareTo(p1.getName());
        if(i == 0) 
            return p2.getAge() - p1.getAge();
        
        return i;
    }
    
}

 

 

 

2.字符串去重按字典逆序打印

/*将字符串去重按字典逆序排序打印
 * 思路:利用TreeSet元素有顺序且不重复的特点
 *        将字符串转为字符数组并存入TreeSet集合
 *   取出元素放入StringBuffer中
 *   调用StringBuffer的reverse()和toString方法
 *      打印
 */

package com.fan.testmain;

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

public class Test3 {


        public static void main(String[] args) {
            
            String s1 = "fdjakfljdaffjklasfjkldqwewqedasfdas";
            
            UniqueSort(s1); //调用排序方法
            
            
        }
        
        
        
        public static void UniqueSort(String s) {
            
            char[] cs = s.toCharArray();  //将字符串转换为字符数组
            TreeSet<Character> ts = new TreeSet(); //创建TreeSet集合。
            
            for(char c : cs) {     //遍历字符数组,将字符加入TreeSet集合

                ts.add(c);
            }
            
            Iterator<Character> it = ts.iterator(); //遍历TreeSet集合,将其中元素取出加入到StringBuffer中
            StringBuffer sb = new StringBuffer();
            
            while(it.hasNext()) {
                
                sb.append(it.next());
            }
            
            String s2 = sb.reverse().toString(); //转换为字符串
            
            System.out.println(s2);
        }
    
}

 数据机构:哈希表

哈希表它可以提供快速的插入操作和查找操作。

数组里面存着链表的头节点。散列函数f(key) % len 存储

四、Map(K,V)

         |--Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。JDK1.0,效率低。

            |--HashMap:底层是哈希表数据结构。允许使用null键null值,该集合是不同步的。JDK1.2,效率高。

            |--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给Map集合中的键进行排序。

常用方法

        Vput(K key,V value);//添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应值,并put方法会返回被覆盖的值。

        voidputAll(Map <? extends K,? extends V> m);//添加一个集合

        clear();//清空

        Vremove(Object key);//删除指定键值对

判断

        containsKey(Objectkey);//判断键是否存在

        containsValue(Objectvalue)//判断值是否存在

        isEmpty();//判断是否为空

获取

        get(Object key);//通过键获取对应的值

        size();//获取集合的长度

        Collection<V>value();//获取Map集合中所有值,返回一个Collection集合

 

        Set<Map.Entry<K,V>>entrySet();

        Set<K>  keySet();

 

遍历取出两种方式

 Set<Map.Entry<K,V>>entrySet();

 Set<K>  keySet();

 

    public static void keySet(HashMap hm)  {  //通过KeSet获取键集遍历
            
            Set<Integer> s = hm.keySet();
            
            Iterator it = s.iterator(); 
            while(it.hasNext()) {
                
                System.out.println(hm.get(it.next()));
            }
            
        }
        
        public static void entrySet(HashMap hm) {  //通过映射关系Entry< , >遍历
            Set<Entry<Integer,Person>> s1 = hm.entrySet();
            
            Iterator<Entry<Integer,Person>> it1 = s1.iterator(); 
            while(it1.hasNext()) {
                
                Map.Entry<Integer, Person> me= it1.next();
                
                System.out.println(me.getKey()+"------"+me.getValue());
            }
        }

程序举例

统计字符串出现的次数并排序,输出格式a(2)b(3)c(1)d(4).............

public class Test4 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String s = "abcdabcdabcaba";
        
        System.out.println(stringSort(s));
    }
    
    
    
    
    
    public static String stringSort(String s) {
        
        
        char[] sc = s.toCharArray();  //转换为字符数组
        TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
        
        for(char i : sc) {   //遍历字符数组
            
            if(!tm.containsKey(i))  //如果TreeMap中没有该字符元素,则put(i,1)
                tm.put(i, 1);
            else {
                tm.put(i, tm.get(i)+1);  //否则值+1
            }
            
        
        }
        
        Iterator<Map.Entry<Character,Integer>> it = tm.entrySet().iterator(); //遍历TreeMAP
        StringBuffer sb = new StringBuffer();
        while(it.hasNext()) {
            
            Map.Entry<Character, Integer> me = it.next();//通过Entry获取映射
            sb.append(me.getKey()+"("+me.getValue()+")"); //通过Entry获取Key和Value
        }
        
        String s1 = sb.toString(); //利用StringBuffer转换为字符串
        
        
        return s1;//返回
    }

}

posted on 2017-10-16 20:24  VinceStarry  阅读(160)  评论(0编辑  收藏  举报

导航