java集合(上)

一、集合概述
集合类的特点
集合是用来封装对象的。
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象
二、Collection
常用的两个子接口:
List:元素有序,可重复,因为其中元素有索引。
set: 无序(无下标),不可重复。
(1)add方法的参数类型是Object。以便于接收任意类型对象。
(2)集合中存储的都是对象的引用(地址)
示例:

Person  p = new Person();
ArrayList l = new ArrayList();
l.add(p);

这里写图片描述
数组转化成集合
ArrayList aList = new ArrayList(Arrays.asList(str));
将集合转化成数组
toArray():返回包含此 collection 中所有元素的数组。
1、Collection的子接口List和Set
(1).List
List:元素是有序的,元素可以重复。因为该集合体系有索引。
|–ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步(线程无联系),不安全。
|–LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。
|–Vector:底层是数组数据结构。线程同步。被ArrayList替代了。因为效率低,但是安全。
(List集合判断元素是否相同,依据是元素的equals方法。当存储时会自动调用。)
List的特有方法:凡是可以操作角标的方法都是该体系特有的方法。

add(index,element);
addAll(index,Collection);

remove(index);

set(index,element);

get(index):获取角标
subList(from,to):截取
ListIterator():获取迭代器
int indexOf(obj):获取指定元素的位置。
List集合特有的迭代器。ListIterator是Iterator的子接口。
在迭代时,不可以通过集合对象的方法操作集合中的元素。
因为会发生ConcurrentModificationException异常。
所以,在迭代器时,只能用迭代器的放过操作元素,可是Iterator方法是有限的,
只能对元素进行判断,取出,删除的操作,
如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。
该接口只能通过List集合的listIterator方法获取。
(1)LinkeList
底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。
特有方法:
addFirst(); addLast();
getFirst(); getLast();
获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException
removeFirst(); removeLast();
LinkedList的部分方法已经升级。JDK1.6以后。
removeLast(); 获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementException
pollLast();获取元素,但是元素被删除。如果集合中没有元素,会返回null。
(2)ArrayList
底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步(线程无联系),不安全。
练习:
删除list集合中的重复元素

package CollectionDemo;
import java.util.*;
public class DeleOver {
    public static void main(String[] args) {
         ArrayList<String> l1 = new ArrayList<String>();
         l1.add("PHP1");
         l1.add("PHP2");
         l1.add("PHP3");
         l1.add("PHP4");
         l1.add("PHP1");
         l1.add("PHP2");
         l1.add("PHP3");
         l1.add("PHP2");
         l1.add("PHP2");
         for(int i = 0;i<l1.size();i++){
             for(int j =i+1;j<l1.size();j++){
                if(l1.get(i).equals(l1.get(j))){
                    l1.remove(j);
                    j--;
                } 
             }
         }
/*       ArrayList<String> l2 = new ArrayList<String>();
         Iterator it  = l1.iterator();
         while(it.hasNext()){
             String strValue = it.next().toString(); 
             if(!l2.contains(strValue)){
                 l2.add(strValue);
             }
         }*/
         //遍历l2
         Iterator it = l1.iterator();
         while(it.hasNext()){
             System.out.print(it.next().toString());
         }
    }

}

(3)Vector
底层是数组数据结构。线程同步。被ArrayList替代了。因为效率低,但是安全。
枚举是Vector特有的取出方式。

        Vector v = new Vector();
        v.add("Ruby01");
        v.add("Ruby02");
        v.add("Ruby03");
        //枚举方式取出
        Enumeration en = v.elements();
        while(en.hasMoreElements()){
            System.out.println(en.nextElement());
        }

需求:使用LinkedList模拟堆栈和队列的数据结构
队列:先进先出

class Queue{
    private LinkedList link;
    Queue(){
        link = new LinkedList();
    }
    public void add(Object o){
        link.addFirst(o);
    }
    public Object remove(){
        return link.removeLast();
}
    public boolean isEmpty(){
        return link.isEmpty();
    }

}

栈:先进后出
稍微修改下

class Stack{
    private LinkedList link;
    Queue(){
        link = new LinkedList();
    }
    public void add(Object o){
        link.addFirst(o);
    }
    public Object remove(){
        return link.removeFirst();
}
    public boolean isEmpty(){
        return link.isEmpty();
    }

}

注意list集合保证对象的唯一性是用equals方法,若对象类没有重写equals方法,则默认调用Object的equals方法。

2、Set集合
Set集合元素无序且不可以重复。
(1)HashSet如何保证元素唯一性?
当哈希表中出现两个相同的对象时:要先判断hashCode值是否相同,若相同,再使用equals判断对象是否相同。若不是一个对象,那么这个会对象存储顺延,还在原位置。其中涉及两个方法:hashCode和equals来完成。
如果元素的HashCode值相同,才会判断equals是否为true。
如果元素的hashcode值不同,不会调用equals。
注意,对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法。
那么当hashSet中不允许存入相同的对象时必须复写hashcode方法和equals方法。
判断删除:先判断hashCode值,然后判断内容。

class Person{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    Person(String name ,int age){
        this.name = name ;
        this.age = age ;
    }
    //重写equals方法
    public boolean equals(Object obj){
        if(!(obj instanceof Person)){
            return false;
        }
        Person p = (Person)obj;
        System.out.println("equals has been called");
        return this.name.equals(p.getName())&&this.age ==p.getAge();

    }
    //重写hashCode方法
    public int hashCode(){
        System.out.println("hashCode has been called");
        return this.name.hashCode()+age;
    }
}

(2)TreeSet:可以对set集合中的元素进行自动排序
需求:TreeSet中存储自定义对象,按照某种规则排序

package CollectionDemo;
import java.util.*;
class Person implements Comparable{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    Person(String name ,int age){
        this.name = name ;
        this.age = age ;
    }
    //继承Comparable,重写compareTo方法
  public   int compareTo(Object obj){
        if(!(obj instanceof Person)){
            throw new RuntimeException("不是Person对象");
        }
        Person p = (Person)obj; 
        if(this.age>p.getAge()){
            return 1;
        }else if(this.age ==p.getAge()){
            return this.name.compareTo(p.getName());//调用String的compareTo方法
        }
        return -1;
    }
}
public class Demo1 {

    public static void main(String[] args) {
       TreeSet hs = new TreeSet();
       hs.add(new Person("zhangsaa",19));
       hs.add(new Person("zhangsac",19));
       hs.add(new Person("zhangsab",19));
       hs.add(new Person("lisi",22));
       hs.add(new Person("xiaoliu",20));
       for(Iterator it1 = hs.iterator();it1.hasNext();){
           Person p = (Person)it1.next();
           System.out.println(p.getName()+" "+p.getAge());
       }
    }

}

TreeSet底层数据结构是二叉树,保证元素的唯一性的依据:compareTo方法return 0。只要return 0,该对象不会存入TreeSet容器。
TreeSet会进行自动排序,方式有两种。
(1)让对象自身具备可比性,需实现Comparable接口,重写 compareTo方法。
(2)当对象不具备比较性时,让集合自身具备比较功能。

//TreeSet定义方式。
TreeSet hs = new TreeSet(new Comparator() {
           public int compare(Object o1, Object o2){
              Person p1 = (Person)o1;
              Person p2 = (Person)o2;
              int i = p1.getAge()-p2.getAge();
              if(i==0){
                  i = p1.getName().compareTo(p2.getName());
              }
              return i;
           }
       });

练习:TreeSet容器实现字符串长度排序

package CollectionDemo;
import java.util.*;
public class Demo2 {
    public static void main(String[] args) {
    TreeSet ts = new TreeSet(new Comparator(){
        public int compare(Object o1,Object o2){
            int i = o1.toString().length() - o2.toString().length();
            if(i==0) {
                 //如果长度一致就错啦。。。还需继续判断!!!return为0绝对会剔除。
                i =  o1.toString().compareTo(o2.toString());
            }
            return i;
        }

    });
    ts.add("aaaa");
    ts.add("aa");
    ts.add("aab");
    ts.add("aaa");
    Iterator it = ts.iterator();
    while(it.hasNext()){
        System.out.println(it.next().toString());
    }
    }

}

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

import java.util.*;
import java.util.Map.Entry;
public class TestDemo {

    /**
     * 需求:"adasdweasdfgagfaga"获取该字符串中的字母出现的次数。
     *  希望打印结果:a(1)c(2).....
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Map<Character, Integer> map = new TreeMap<Character, Integer>();
        String str = "adasdweasdfgagfaga";
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            // 判断是否在其中
            if (map.containsKey(c)) {
                map.put(c, map.get(c) + 1);
            } else {
                map.put(c, 1);
            }
        }
        // 遍历map集合
        for (Entry<Character, Integer> entry : map.entrySet()) {
            System.out.print(entry.getKey() + "(" + entry.getValue() + ")");
        }

    }
}

输出结果

a(6)d(3)e(1)f(2)g(3)s(2)w(1)

“`

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_26439387/article/details/46820825
文章标签: 遍历集合 set 集合
个人分类: java基础
想对作者说点什么? 我来说一句

Java Generics and Collections

2018年05月09日 2.13MB 下载

JAVA 经典算法书集合(1)

2011年06月27日 10.57MB 下载

java集合与映射(牛)

2009年04月28日 3KB 下载

java 文件管理集合

2010年07月11日 6KB 下载

java集合框架图

2011年10月18日 313KB 下载

java集合API

2007年11月05日 204KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭