黑马程序员--集合类


------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------



集合类


为什么出现集合类?

面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。

 

数组和集合类同是容器,有何不同?

数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。

 

集合类的特点:

集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。(可以加入泛型。)

 

 

Java中集合类的关系图:

 

为什么会有这么多不同的容器呢?

因为每个存储的类型不同,作用不同,便分成了不同的容器。

 

接下来便说说Collection容器和其常用子类吧。

Collection

         |--List:元素是有序的,元素可以重复。因为该集合体系有索引。

                   |--ArrayList:底层的数据结构使用的是数组结构

                   |--LinkedList:底层使用的是链表数据结构。   

                  |--vector:底层是数组数据结构。线程同步,被ArrayList替代了。

         |--Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。

                   |--HashSet:底层数据结构是哈希表.

                   |--TreeSet:Set集合的功能和Collection是一致的。

-------------------------------------------------------------------------------

List:

         List特有方法。凡是可以操作角标的方法都是该体系特有的方法。

 

         add(index,element);

         addAll(index,Collection);

         remove(intindex);

         set(index,element);

         get(intindex):

         subList(from,to);

         listIterator();

 

List集合特有的迭代器ListIterator是Iterator的子接口。

 

在迭代时,不可以通过集合对象的方法操作集合中的元素。

因为会发生.ConcurrentModificationException异常。

 

所以,在迭代式,只能有迭代器的方法操作元素。可是Iterator方法是有限的,

只能对元素进行判断。取出,删除的操作。

如果想要其他的操作如添加。修改等,就需要使用期子接口,ListIterator.

 

该接口只能通过List集合的ListIterator方法获取。

 

ListIterator:

  List 集合特有的迭代器。ListIterator 是Iterator的子接口

  在迭代式中,不可以通过集合对象的方法操作集合的元素。因为会发生ConcurrentModificationException 异常

  所以在迭代时,只能用迭代器的方法操作元素,可是Iterator方法方法是有限的

  只能对元素进行判断,取出,删除的操作。

  如果想要其他的操作如添加,修改等,就需要使用起接口,ListIterator。

  该接口只能通过List的Iterator方法获取

 

 

ArrayList:

底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。

1,  可以添加任意类型的元素,方便与取出。

2,  集合中存储的并非为某个内容,而是将对象的引用(地址)存于ArrayList上。

 

LinkedList:

运用链表结构,特点,增删速度快,查询稍慢。

 

LinkedList:特有方法。

addFirst();

addLast();

 

getFirst();

getLast();

获取元素但不删除元素。会出现NoSuchElementException.

 

removeFirst();

removeLast();

获取元素,但是元素被删除。如果集合中没有元素。会出现NoSuchElementException.

 

在JDK 1.6中出现了替代方法。

 

offerFirst();

offerLast();

 

peekFirst();

peekLast();

获取元素,但不会删除元素。如果集合中没有元素。会返回null

 

pollFirst();

pollLast();

获取元素,但是元素会被删除。如果集合中没有元素。会返回null

LinkedList示例:

 

package com.itheima;

 

import java.util.LinkedList;

/*

使用LinkedList魔力一个堆栈或者队列数据结构。

 

堆栈:先进后出。如同一个杯子。

队列:先进先出。First in First out FIFO如同一个水管。

 */

 

public class LinkedListDemo {

    public static void main(String[] args) {

       LinkedList ll = new LinkedList();

       ll.add("i");

       ll.add("t");

       ll.add("h");

       ll.add("e");

       ll.add("i");

       ll.add("m");

       ll.add("a");

       duiZhan(ll);

       FIFO(ll);

    }

    public static void duiZhan(LinkedList oldLin){

       LinkedList newLin = new LinkedList();

       newLin.add(oldLin);

       if(newLin.size()!=0){

           while (!newLin.isEmpty()) {

              System.out.print(newLin.removeLast());

           }

       }else{

           System.out.println("集合长度为空。");

       }

    }

    public static void FIFO(LinkedList oldLin){

       LinkedList newLin = new LinkedList();

       newLin.add(oldLin);

       if(newLin.size()!=0){

           while (!newLin.isEmpty()) {

              System.out.print(newLin.removeFirst());

           }

       }else{

           System.out.println("集合长度为空。");

       }

    }

}

 

迭代:

 

迭代是取出集合中元素的一种方式。

因为Collection中有iterator方法,所以每一个子类集合对象都具备迭代器。

用法:

    for (Iterator iter=ll.iterator() ; iter.hasNext();) {

       System.out.println(iter.next());

    }

    Iterator iter = ll.iterator();

    while (iter.hasNext()) {

       System.out.println(iter.next());

    }

在使用迭代时,迭代器的next方法是自动向下取元素,要避免出现NoSuchElementException。并且迭代器的next方法返回值类型是Object,因为可以让其返回所有的类,所以要记得类型转换。

 

 

Set接口

 

1)Set是Collection子接口;

2)Set和Collection基本上一样,一点除外:

3)Set无法记住添加的顺序,不允许包含重复的元素。

当试图添加两个相同元素进Set集合,添加操作失败,add()方法返回false。

4)Set判断两个对象是否相等用equals,而不是使用==。

也就是说两个对象equals比较返回true,Set集合是不会接受这个两个对象的。

常用子类:

HashSet:散列存放

TreeSet:有序存放

 

 

 

HashSet

HashSet底层数据结构是哈希表。那么HashSet是如何保证元素唯一性的呢?是通过元素的两个方法,hashCode和equals来完成。如果元素的HashCode相同,才会判断equals是否为true。如果元素的hashCode不同。不会调用equals。注意,对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。线程不安全的,多个线程访问一个HashSet要使用同步代码, HashSet集合元素值允许是null。

所以当HashSet添加元素时,首先会调用hashCode()方法计算哈希值,判断哈希值是否相同,如果不同则会按区域将元素添加进去;当相同时,会调用equals方法比较,在equals方法中比较如果相同则不会添加。

注:覆盖equalshashCode时可以运用Eclipse覆盖功能,当一个对象被储存进HashSet集合后,就不能修改这个这个对象的那些参与哈希值运算的字段了,否则,对象修改后的哈希值与最初储存进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结过,这也会导致无法从HashSet集合中单独删除当前对象,从而造成内存泄露。

 

 

 

示例:

package com.itheima;

 

import java.util.HashSet;

 

public class HashSetDemo {

    public static void main(String[] args) {

       HashSet s = new HashSet();

       s.add(new Person("李四",21));

       s.add(new Person("李四",21));

       s.add(new Person("李四",21));

       s.add(new Person("李四",21));

       System.out.println(s.size());

       //没有覆盖hashCodeequals之前s.size()=4;

       //覆盖hashCode,equalss.size()=1;

    }

}

class Person{

    public String name ;

    public int age;

    public Person(String name, int age) {

       super();

       this.name = name;

       this.age=age;

    }

    @Override

    public int hashCode() {

       final int prime = 31;

       int result = 1;

       result = prime * result + age;

       result = prime * result + ((name == null) ? 0 : name.hashCode());

       return result;

    }

    @Override

    public boolean equals(Object obj) {

       if (this == obj)

           return true;

       if (obj == null)

           return false;

       if (getClass() != obj.getClass())

           return false;

       Person other = (Person) obj;

       if (age != other.age)

           return false;

       if (name == null) {

           if (other.name != null)

              return false;

       } else if (!name.equals(other.name))

           return false;

       return true;

    }

}

 

TreeSet

底层使用的是二叉树结构,不允许重复元素,无序。排序时TreeSet会调用元素的compareTo(Objecto)方法来比较元素之间的大小关系,然后将集合里的元素按升序排列.此时需要排序元素的类必须实现Compareble接口,并覆写其int compareTo(Object o)方法;

 

TreeSet是SortedSet接口唯一的实现,与HashSet相比额外的方法有:

Comparatorcomparator():返回当前Set使用的Comparator,若返回null,表示以自然顺序排序。

Objectfirst() 返回此 set 中当前第一个(最低)元素。

Objectlast() 返回此 set 中当前最后一个(最高)元素。

SortedSetsubSet(Object  fromElement, E toElement) 返回此 set 的部子集,其元素从 fromElement(包括)到 toElement(不包括)。

SortedSetheadSet(Object  toElement)返回此 set 的部分子集,其元素严格小于toElement。

SortedSet tailSet(Object  fromElement) 返回此 set 的部分子集,其元素大于等于fromElement。

 

TreeSet会将所有元素进行自然排序,通过compareTo(Objectobj)方法,若obj.compareTo(obj2), 返回0,表示两个对象相等,若返回一个正整数,表示obj1大于obj2,若返回一个负整数,表示obj1小于obj2。

TreeSet示例:

package com.itheima;

 

import java.util.TreeSet;

 

//int元素进行自然排序。

public class TreeSetDemo {

    public static void main(String[] args) {

       TreeSet tr = new TreeSet();

       tr.add(new Student(35));

       tr.add(new Student(25));

       tr.add(new Student(75));

       tr.add(new Student(3));

       tr.add(new Student(1));

       tr.add(new Student(100));

       System.out.println(tr);

// [Student[id=1], Student [id=3], Student [id=25], Student [id=35], Student [id=75],Student [id=100]]

 

    }

}

class Student implements Comparable{

    private int id = 0;

 

    public Student(int id) {

       super();

       this.id = id;

    }

 

    @Override

    public int compareTo(Object o) {

       // TODO Auto-generated method stub

       if(o instanceof Student){

           Student s = (Student)o;

           return Integer.compare(id, s.id);

       }

       return 0;

    }

 

    @Override

    public String toString(){

       return "Student[id=" + id + "]";

    }

   

}

 

自定义TreeSet排序方式:

    想要依据自己的排序方式对TreeSet进行排序,例如降序和升序,那么这是就需要去实现Comparator接口了:简单实现

package com.itheima;

 

import java.util.Comparator;

import java.util.TreeSet;

 

public class TreeSetDemo2 {

    public static void main(String[] args) {

//     TreeSet tr = new TreeSet(new downCom());

//[Student[id=3], Student [id=23], Student [id=44], Student [id=1], Student [id=5],Student [id=23]]

       TreeSet tr = new TreeSet(new upCom());

//[Student[id=23], Student [id=5], Student [id=1], Student [id=44], Student [id=23],Student [id=3]]

      

       tr.add(new Student(3));

       tr.add(new Student(23));

       tr.add(new Student(44));

       tr.add(new Student(1));

       tr.add(new Student(5));

       tr.add(new Student(23));

       System.out.println(tr);

    }

}

class Student2{

    private int age;

 

    public Student2(int age) {

       super();

       this.age = age;

    }

 

    public int getAge() {

       return age;

    }

 

    public void setAge(int age) {

       this.age = age;

    }

}

class upCom implements Comparator{

 

    @Override

    public int compare(Object o1, Object o2) {

       // TODO Auto-generated method stub

       return -1;

    }

   

}

class downCom implements Comparator{

 

    @Override

    public int compare(Object o1, Object o2) {

       // TODO Auto-generated method stub

       return 1;

    }

   

}

 

 

Map接口

Map接口,键值对关系,在Map集合中,值允许重复,键不允许重复,可以通过唯一的键找到所对应的值。 

 

Map接口实现子类:

|--Hashtable:底层是哈希表数据结构,不可以存入null值,null键。

                            该集合是同步的,JDK1.0

|--HashMap:底层是哈希表数据结构,允许使用null值,null键。

                            该集合是不同步的,JDK1.2,效率更高。

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

 

*Set很像,其实Set底层运用的就是Map方法。

 

 

 

Map常用方法

 

void clear():删除该Map对象中所有的key-value对。也就是清理该集合;

booleancontainsKey(Object key):查询Map中是否包含指定的key;

booleancontainsValue(Object  value):查询Map中是否包含至少一个value;

Set<Map.Entry<K,V>>entrySet():返回Map所包含的key-value对所组成的Set集合,每个集合元素都是Map.Entry对象(Entry是Map内部类);

Object get(Objectkey):返回指定key所对应的value,若此Map中不包含该key,返回null;

boolean isEmpty():判断Map集合是否为空;

Set keySet():返回该Map中所有key所组成的Set集合;

Object put(Objectkey,Object value):添加一个key-value对,若Map中已有与key相等的key-value对,则新的key-value对覆盖原来的key-value对;

void putAll(Map m):将m中的key-value赋值到调用该方法的Map对象中;

Object remove(Objectkey):删除key所对应的key-value对,返回本删除key所关联的value,若key不存在,返回null;

int size():返回该Map里面key-value对的个数;

Collection values():返回Map里所有value组成的Collection。

 

Map示例:

package com.itheima;

 

import java.util.Collection;

import java.util.HashMap;

import java.util.Map;

import java.util.Set;

 

public class MapDemo {

    public static void main(String[] args) {

       Map map = new HashMap();

       map.put(1, "张三");

       map.put(2, "李四");

       map.put(3, "王五");

       map.put(4, "赵六");

       //判断是Map是否为空。

       System.out.println(map.isEmpty());

       //判断是否有指定的key

       System.out.println(map.containsKey(5));

       //判断是否有指定的value

       System.out.println(map.containsValue("王七"));

       //获得Map的长度

       System.out.println(map.size());

      

       System.out.println(map);

//     {1=张三, 2=李四, 3=王五, 4=赵六}

      

       Set set= map.entrySet();

       System.out.println(set);

//     [1=张三, 2=李四, 3=王五, 4=赵六]

      

       //获得所有的键。

       set = map.keySet();

       System.out.println(set);

//     [1, 2, 3, 4]

      

       for (Object key : set) {

           System.out.println("键为:"+key);

           //获得键对应的值。

           System.out.println("值为:"+map.get(key));

       }

       /*

键为:1

值为:张三

键为:2

值为:李四

键为:3

值为:王五

键为:4

值为:赵六

        */

       //删除指定key所对应的key-value对,如key不存在,则返回value

       map.remove(2);

       System.out.println(map.size()+"::"+map);

       //3::{1=张三, 3=王五, 4=赵六}

       //返回Map中所有的值。

       Collection con = map.values();

       System.out.println(con);

       //[张三, 王五, 赵六]

 

    }

}

Map.Entry<K,V>

Entry是Map接口的一个内部接口,该接口用于封装Key-Value。

Map集合常用方法:

Object getKey();返回Entry里包含的key值

Object getValue();返回Entry里包含的value值

Object setValue(Object value):设置Entry里包含的value值,并返回新设置的value值;

 

Map集合可以通过调用entrySet方法变成Set对象,然后通过调用Iterator,此时每个方法都是Map.Entry对象,然后将每个Map.Entry对象分离出键值对。

示例:

package com.itheima;

 

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

 

public class MapEntryDemo {

    public static void main(String[] args) {

       Map<Integer, String> map = new HashMap<Integer, String>();

       map.put(1, "张三");

       map.put(2, "李四");

       map.put(3, "王五");

       map.put(4, "赵六");

       //获得Map.Entry

       Set<Entry<Integer, String>> set = map.entrySet();

       //通过迭代器获得每个Map.Entry

       Iterator<Entry<Integer,String>> iter = set.iterator();

       while (iter.hasNext()) {

           Map.Entry<Integer,String> entry =(Map.Entry<Integer,String>) iter

                  .next();

           //获得键和值

           System.out.println(entry.getKey() + entry.getValue());

       }

      

    }

}

 

Collections类

 

集合框架的工具类:      àjava.util.Collections

static void reverse(List list):反转指定List集合中的顺序;(和ListItertor的逆序排列一样!)

static void shuffle(List list):对集合元素随机排序

static void sort(List list):自然升序排序

static vois swap(List list,int i, int j):将指定的List集合i处元素和j处元素进行交换;

static void rotate(List list, intdistance):

         若distance为正数,将list集合后的distance个元素移到前面;

         当distance为负数,将list集合前的distance个元素移到后面;

static int binarySearch(List list, Object key) 使用二分搜索法搜索指定列表,以获得指定对象。

调用之前必须调用 Collections.sort(List list)(完成自然排序);

 

static Object max(Collection coll) 根据元素的自然顺序,返回给定 collection 的最大元素。  

static Object min(Collection coll) 根据元素的自然顺序,返回给定 collection 的最小元素。        

static void fill(List list, Object obj)  使用指定元素替换指定列表中的所有元素。

static int frequency(Collection c, Objecto)  返回指定 collection 中等于指定对象的元素数。

static int indexOfSubList(Listsource, Listtarget) 返回指定源列表中第一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。

static int lastIndexOfSubList(List source,List target)  返回指定源列表中最后一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。

static boolean  replaceAll(List list, Object oldVal, ObjectnewVal)  使用另一个值替换列表中出现的所有某一指定值。

 

Arrays:

 List<T> asLIst(T…a)返回一个受指定数组支持的固定大小的列表,把数组变成list集合有什么好处?

可以是用集合的思想和方法,来操作元素。

注意:将数组变成集合,不可以使用集合的增删方法,因为数组的长度是固定的,可以使用:contains,get,indexOf,subList等方法。 如果使用增删方法,则会出现VnspportedOperationException(不支持操作异常)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值