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)

“`

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值