java基础学习集合学习笔记

本文深入讲解Java集合框架的各类集合,包括List、Set、Map及其子类的特点与使用方法,对比不同集合之间的区别,帮助读者理解集合的工作原理并正确选择适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


------- android培训java培训、期待与您交流! ----------

集合



(1)集合的由来和特点
  A:由来
   java中描述数据的最基本单位就是类,为了方便对多个对象进行存储和遍历,
   java提供了一种新的存储数据的容器,叫集合类。
  B:特点
   长度可以变化。
   只能存储对象。
(2)集合和数组的区别
  A:集合
   只能存储对象
   长度可以变化
  B:数组
   可以存储基本数据类型,也可以存储对象类型
   长度固定
(3)集合体系的由来
  由于每个集合类的数据结构不同,所以,集合会有很多的子类。
  但是,这些子类不断的向上抽取共性内容,最终形成了集合体系。

  一个体系的学习和使用方式:
   学习顶层:顶层定义的是这个体系的共性内容。
   使用底层:底层才是具体的存在的实现类。

一、Collection接口中的常见操作


   添加元素:
    boolean add(Object obj)
   删除元素:
    void clear()
    boolean remove(Object obj)
   判断元素:
    boolean isEmpty()
    boolean contains(Object obj)
   长度:
    int size()
   迭代器:
    Iterator iterator()

 

  A:存储字符串
   //创建集合对象
   Collection c = new ArrayList();

   //创建元素对象
   String s1 = "haha";
   String s2 = "hehe";
   String s3 = "xixi";

   //把元素对象添加到集合对象中
   c.add(s1);
   c.add(s2);
   c.add(s3);


   }

二、迭代

1、概述

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

        对于集合的元素取出这个动作:

        当不足以用一个函数来描述,需要用多个功能来体现,所以就将取出这个动作封装成一个对象来描述。就把取出方式定义在集合的内部,这样取出方式就可以直接访问集合内部的元素。那么取出方式就被定义成了内部类。

        而每一个容器的数据结构不同,所以取出的动作细节也不一样。但是都具有共性内容: 判断和取出。那么就可以将这些共性抽取。

         那么这些内部类都符合一个规则(或者说都抽取出来一个规则)。该规则就是Iterator。通过一个对外提供的方法:iterator();,来获取集合的取出对象。

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

 

2、迭代的常见操作

        hasNext();//有下一个元素,返回真

        next();//取出下一个元素

        remove();//移除

注:在迭代时循环中next调用一次,就要hasNext判断一次。

使用:

         ArrayList a=newArrayList();//创建一个集合

        Iteratorit=a.iterator();//获取一个迭代器,用于取出集合中的元素。

        第一种打印方式:

                for(Iterator iter = a.iterator();iter.hasNext();  )

                {

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

                }

       第二种打印方式:

                 Iteratoriter = a.iterator();

                while(iter.hasNext())

               {

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

               }

3、迭代注意事项

  • 迭代器在Collcection接口中是通用的,它替代了Vector类中的Enumeration(枚举)
  • 迭代器的next方法是自动向下取元素,要避免出现NoSuchElementException
  • 迭代器的next方法返回值类型是Object,所以要记得类型转换。


             List   集合


(1)掌握如下体系结构图
  List 元素有序,可重复。
   |--ArrayList
    底层数据结构是数组,查询快,增删慢。
    线程不安全,效率高。
   |--Vector
    底层数据结构是数组,查询快,增删慢。
    线程安全,效率低。
   |--LinkedList
    底层数据结构是链表,查询慢,增删快。
    线程不安全,效率高。
(2)List的特有功能
  A:添加元素
   add(int index,Object obj)
  B:删除元素
   remove(int index)
  C:获取元素
   get(int index)
  D:列表迭代器
   ListIterator listIterator()
  E:修改元素
   set(int index,Object obj)

  ArrayList  集合

案例:
   **存储遍历字符串

   //创建集合对象
   List list = new ArrayList();

   //创建元素对象
   String s1 = "haha";
   String s2 = "hehe";
   String s3 = "xixi";

   //把元素对象添加到集合对象中
   list.add(s1);
   list.add(s2);
   list.add(s3);

   通过迭代器遍历集合元素
   Iterator it = list.iterator();
   while(it.hasNext())
   {
    String s = (String) it.next();
    System.out.println(s);
   }

ListIterator

1、概述 

        ListIteratorList集合特有的迭代器,是Iterator的子接口。

       在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。所以在迭代器时,只能用迭代器的方法操作元素。可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作。如果想要其他的操作,如添加、修改等,就需要使用其子接口:ListIterrator。该接口只能通过List集合的ListIterator方法获取。

2ListIterator特有的方法

        add(obj);//增加

        set(obj);//修改为obj

        hasPrevious();//判断前面有没有元素

        previous();//取前一个元素


   **存储遍历自定义对象(Student已经存在,name和age)
  
   List list = new ArrayList();

   Student s1 = new Student("唐三角",20);
   Student s2 = new Student("孙悟空",25);
   Student s3 = new Student("猪八戒",22);


   list.add(s1);
   list.add(s2);
   list.add(s3);

   //遍历
   Iterator it = list.iterator();
   while(it.hasNext())
   {
    Student s = (Student)it.next();
    System.out.println(s.getName()+"***"+s.getAge());
   }

   for(int x=0; x<list.size(); x++)
   {
    Student s = (Student) list.get(x);
    System.out.println(s.getName()+"***"+s.getAge());
   }
(3)List体系下的这个三个集合类用哪一个比较好:
  A:如果是要求查询快,就使用ArrayList
  B:如果是要求增删多比较多,就使用LinkedList
  C:如果涉及多线程安全问题,就使用Vector
(4)注意:ArrayList的contains方法底层依赖的是equals方法。

枚举Enumeration

枚举:

        就是Vector特有的取出方式。Vector有三种取出方式。

        其实枚举和迭代是一样的。因为枚举的名称以及方法的名称都过长。所以被迭代器取代了。

特有方法:

         addElement(obj);//添加元素,相当于add(obj);

         Enumerationelements();//Vector特有取出方式(枚举)

         hasMoreElements();//相当于IteratorhasNext()方法

         nextElements();//相当于Iteratornext()方法

例:

Vector v=new Vector();
for(Enumeration e=v.elements();e.hasMoreElements();)
{
System.out.println(e.nextElements());
}  

LinkedList

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

特有方法:

1、增

        addFirst();

        addLast();

2、获取

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

        getFirst();

        getLast();

3、删

        //获取元素,并删除元素。如果集合中没有元素,会出现NoSuchElementException

        removeFirst();

        removeLast();

JDK1.6以后,出现了替代方法。

1、增

        offFirst();

        offLast();

2、获取

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

        peekFirst();

        peekLast();

3、删

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

        pollFirst();

        pollLast();




Set  集合

HasSet

        HashSet:线程不安全,存取速度快。

       可以通过元素的两个方法,hashCodeequals来完成保证元素唯一性。如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashCode值不同,不会调用equals

注意:HashSet对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCodeequals方法。

示例:



  public class Student
  {
   private String name;
   private int age;

   public Student(){}

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

   //get/set...

   public int hashCode()
   {
    return this.name.hashCode()+this.age*11;
   }

   public boolean equlas(Object obj)
   {
    if(this==obj)
    {
     return true;
    }

    if(!(obj instanceof Student))
    {
     return false;
    }

    Student s = (Student)obj;
    return this.name.equals(s.name) && this.age==s.age;
   }
  }


  public class HashSetDemo
  {
   public static void main(String[] args)
   {
    HashSet<Student> hs = new HashSet<Student>();

    Student s1 = new Student();
    Student s2 = new Student();
    Student s3 = new Student();

    hs.add(s1);
    hs.add(s2);
    hs.add(s3);

    //遍历
   }
  }

TreeSet

1、特点

        a、底层的数据结构为二叉树结构

        b)可对Set集合中的元素进行排序,是因为:TreeSet类实现了Comparable接口,该接口强制让增加到集合中的对象进行了比较,需要复写compareTo方法,才能让对象按指定需求(如人的年龄大小比较等)进行排序,并加入集合。

        java中的很多类都具备比较性,其实就是实现了Comparable接口。

注意:排序时,当主要条件相同时,按次要条件排序。

Tree排序的两种方式

        1)第一种排序方式:自然排序

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

示例:

import java.util.*;
//学生类
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;
}
//复写hashCode以便HashSet集合调用
public int hashCode()
{
return name.hashCode()+age;
}
//复写equals以便HashSet集合和集合中一些比较方法调用
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException();
Student s = (Student)obj;
return this.name.equals(s.name)&&this.age==s.age;
}
//复写compareTo以便TreeSet集合调用
public int compareTo(Object obj)
{
Student s=(Student)obj;
if(this.age==s.age)
return this.name.compareTo(s.name);
return this.age-s.age;
//return new Integer(this.age).compareTo(new Integer(s.age)); 
}
}


class  TreeSetTest
{
public static void main(String[] args) 
{
TreeSet<Student> t=new TreeSet<Student>();
t.add(new Student("wo1",12));
t.add(new Student("wosj",2));
t.add(new Student("wo1sdj",12));
t.add(new Student("wo6sd",12));
t.add(new Student("wo",22));



for (Iterator<Student> it=t.iterator(); it.hasNext(); )
{
Student s=it.next();
System.out.println(s.getName()+"....."+s.getAge());
}
}
}

        2)第二种方式:比较器

                   当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。

                  在集合初始化时,就有了比较方式。定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

                  比较器构造方式:定义一个类,实现Comparator接口,覆盖compare方法。

                   当两种排序都存在时,以比较器为主。

示例:

/*
需求:
往TreeSet集合中存储自定义对象学生。
想按照学生的年龄进行排序。


*/


import java.util.*;
//学生类
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;
}
//复写hashCode以便HashSet集合调用
public int hashCode()
{
return name.hashCode()+age;
}
//复写equals以便HashSet集合和集合中一些比较方法调用
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException();
Student s = (Student)obj;
return this.name.equals(s.name)&&this.age==s.age;
}
//复写compareTo以便TreeSet集合调用
public int compareTo(Object obj)
{
Student s=(Student)obj;
if(this.age==s.age)
return this.name.compareTo(s.name);
return this.age-s.age;
//return new Integer(this.age).compareTo(new Integer(s.age)); 
}


}


class  TreeSetTest
{
public static void main(String[] args) 
{
TreeSet<Student> t=new TreeSet<Student>(new LenCompare());
t.add(new Student("wo1",12));
t.add(new Student("wosj",2));
t.add(new Student("wo1sdj",12));
t.add(new Student("wo6sd",12));
t.add(new Student("wo",22));



for (Iterator<Student> it=t.iterator(); it.hasNext(); )
{
Student s=it.next();
System.out.println(s.getName()+"....."+s.getAge());
}
}


}
//定义一个比较器,以姓名长度为主要比较
class LenCompare implements Comparator<Student>
{
public int compare(Student s1,Student s2)
{
int num=new Integer(s1.getName().length()).compareTo(new Integer(s2.getName().length()));
if (num==0)
{
return new Integer(s1.getAge()).compareTo(s2.getAge());
}
return num;
}
}

 


 

5:总结


如果你使用的集合要保证元素唯一:Set
  不需要排序:HashSet
    需要排序:TreeSet
如果你使用的集合不用保证元素唯一:List
  查询:ArrayList
  修改:LinkedList
  线程不安全:Vector
小技巧:
Array:说明底层数据结构是数组,查询快,增删慢
Link:说明底层数据结构是链表,查询慢,增删快
Hash:说明底层数据结构是哈希表,保证元素唯一,要依赖hashCode和equals。
Tree:说明底层数据结构是二叉树,有两种方案保证唯一和排序:
  A:Comparable -- compareTo
  B:Comparator -- compare


Map  集合

一、概述

1、简述:

        Map<K,V>集合是一个接口,和List集合及Set集合不同的是,它是双列集合,并且可以给对象加上名字,即键(Key

2、特点:

        1)该集合存储键值对,一对一对往里存

        2)要保证键的唯一性。

 

二、Map集合的子类

        Map

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

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

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

        MapSet很像。其实Set底层就是使用了Map集合。

 


 

三、Map集合的常用方法


  A:添加元素
   put(Object key,Object value):把键值对元素添加到Map集合中
  B:删除元素
   remove(Object key):删除键为key的元素
  C:判断功能
   containsKey(Object key):判断Map集合中是否有键为key的键值
   containsValue(Object value):判断Map集合中是否有值为value的值
  D:获取元素
   get(Object key):根据键获取值
   keySet():获取Map集合的键的Set集合
   values():获取Map集合的值的Collection集合
   entrySet():获取Map集合的键值对的集合
  E:长度
   size():Map集合中键值对元素的个数

  遍历的思路:
   思路1:
    获取键值对的集合 keySet()
    遍历键集合,获取到每个键 Iterator hasNext(),next()
    通过键去找自己的值 get()

   思路2:
    键值对的映射项Map.Entry是Map做好的:
     Map.Entry<Key,Value>
    键值对集合 entrySet()
    遍历键值对集合,获取到每个键值对的映射项Map.Entry对象 Iterator hasNext(),next()
    通过键值对的映射项Map.Entry对象获取键和值 getKey(),getValue()


  案例演示:
   键和值都是字符串:
  
   Map<String,String> map = new HashMap<String,String>();

   map.put("张三", "北京");
   map.put("李四", "上海");
   map.put("王五", "天津");
   map.put("赵六", "重庆");
   map.put("田七", "陕西");

   //方式1
   Set<String> keySet = map.keySet();
   Iterator<String> keyIt = keySet.iterator();
   while(keyIt.hasNext())
   {
    String key = keyIt.next();
    String value = map.get(key);
    System.out.println(key+"***"+value);
   }

   //方式2
   Set<Map.Entry<String,String>> meSet = map.entrySet();
   Iterator<Map.Entry<String,String>> meIt = meSet.iterator();
   while(meIt.hasNext())
   {
    Map.Entry<String,String> me = meIt.next();
    String key = me.getKey();
    String value = me.getValue();
    System.out.println(key+"***"+value);
   }
(3)HashMap
  是如何保证键的唯一性:
  通过自定义对象的hashCode方法和equals方法。

  代码体现:键是自定义对象,值是字符串
  前提:Student重写了hashCode方法和equals方法。

  HashMap<Student,String> hm = new HashMap<Student,String>();

  Student s1 = new Student("科比", 20);
  Student s2 = new Student("霍华德", 22);
  Student s3 = new Student("易建联", 25);
  Student s4 = new Student("乔丹", 24);
  Student s5 = new Student("林书豪", 23);
  Student s6 = new Student("易建联", 25);
  Student s7 = new Student("乔丹", 24);

  hm.put(s1,"北京");
  hm.put(s2,"上海");
  hm.put(s3,"重庆");
  hm.put(s4,"天津");
  hm.put(s5,"武汉");
  hm.put(s6,"深圳");
  hm.put(s7,"石家庄");

  //遍历
  Set<Student> set = hm.keySet();
  Iterator<Student> it = set.iterator();
  while(it.hasNext())
  {
   Student key = it.next();
   String value = hm.get(key);
   System.out.println(key.getName()+"***"+key.getAge()+"***"+value);
  }
  
(4)TreeMap
  是如何保证键的唯一性和排序的:
  集合具备比较性:Comparator -- compare
  元素具备比较性:Comparable -- compareTo

(5)LinkedHashSet和LinkedHashMap
  通过链表保证有序
  通过哈希保证唯一

  LinkedHashSet:保证元素有序,唯一
  LinkedHashMap:保证键有序,唯一
(6)HashMap和Hashtable的区别:
  A:Hashtable是线程安全的,效率低。HashMap是线程不安全的,效率高。
  B:Hashtable的键和值都不能为null。HashMap可以允许null键和null值。


7:工具类的使用


(1)对数组操作的Arrays
  A:static String toString(数组)
  B:static void sort(数组)
    可以对对象数组进行排序。
   两种方式:
    元素具备比较性
    Arrays的sort方法具备比较性
  C:static int binarySearch(数组,值)
   前提:数组有序
  D:static <T> List<T> asList(T... t)
(2)对集合操作的Collections
  A:static void sort()
  B:static void reverse()
  C:static int binarySearch(集合,值)


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值