java基础之集合

集合概念:

长度可以变化。就是一种容器。集合存储只能是对象。

集合框架:

如何学习集合??

1、会使用集合存储数据

2、会遍历集合,数据取出

3、掌握集合特性。

集合架构:

Collection:单列集合根接口,定义了单列集合共性的方法(所有的集合都可以使用),常用如下:没有索引的,不能使用for循环来遍历

public boolean add(E e): 把给定的对象添加到当前集合中 。

public void clear() :清空集合中所有的元素。

public boolean remove(E e): 把给定的对象在当前集合中删除。

public boolean contains(E e): 判断当前集合中是否包含给定的对象。

public boolean isEmpty(): 判断当前集合是否为空。

public int size(): 返回集合中元素的个数。

public Object[] toArray(): 把集合中的元素,存储到数组中。

使用步骤:

1、创建一个集合对象,可以使用多态

2、对象.方法

Iterator接口:也称为迭代器

要解决的问题,就是集合对象遍历问题。通用的取出集合元素的方式。

原理:

在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。

Iterator接口的常用方法如下:

public E next():返回迭代的下一个元素。

public boolean hasNext():如果仍有元素可以迭代,则返回 true。

使用步骤:

因为是接口,需要使用实现类对象,获取对象的方式比较特殊:通过调用Collection接口中的Iterator()方法来实现,返回的就是实现类对象。     Iteratar<E> iterator();     //返回在此collection 的元素上进行迭代的迭代器。

1、使用集合中的方法Iterator()获取迭代类实现对象,使用Iteratorr接口接收(多态)

Iterator<E>也是有泛型的,迭代器的泛型跟着集合走,集合是什么泛型,迭代器就是什么泛型

2、使用Iterator接口中的方法hasNext判断还有没有下一个元素

3、使用next方法取出集合中的下一个元素。

 

增强for循环:专门用来遍历集合和数组的,底层使用的也是迭代器,只是使用for循环的格式,简化迭代器写法。

格式:

for(集合/数组的数据类型  变量名 :(冒号)  集合名/数组名){

        sout(变量名);

}

 

泛型:集合中数据类型就是泛型,可以看成是一种未知的数据类型。也可以看成是一个变量用来接收数据类型。

1、什么时候确定泛型数据类型?

创建集合对象的时候,就会确定泛型的数据类型。

2、使用泛型好处?1、避免类型转换的麻烦。存储是什么类型,取出的就是什么类型 2、运行期异常(即运行之后才抛出的异常),提升到编译期。

3、泛型的类定义和使用?

定义格式:泛型可以接收任意的数据类型

 修饰符 class 类名<代表泛型的变量> { } 

4、含有泛型方法定义和使用?

格式:泛型定义在方法的修饰符和返回值类型之间

      修饰符  <泛型> 返回值类型   方法名(参数列表(使用泛型)){

                    方法体;

};//在调用方法的时候确定泛型的数据类型,传递什么类型的参数,泛型就是什么类型。

5、含有泛型的接口定义和使用?

格式:修饰符 interface接口名<代表泛型的变量> {  }

第一种使用方式:定义接口的实现类,实现接口,指定接口泛型,如:

  public interface Iterator<E> {

                 E  next();

}      //定义类时确定泛型的类型         

Scanner 类实现了Interator接口,并指定接口的泛型为String,所以重写的next方法泛型默认就是String

public final class scanner implements Iterator<String>{

                 public String next(){}

}      

第二种使用方法,接口使用什么泛型,实现类就使用什么泛型,类跟着接口走,就相当于定义了一个含有泛型的类,创建对象的时候确定泛型的类型

如:public interface List<e>{

         boolean add(E e);

          E get(int index);

}

public class ArrayList<e> implements List<E>{

         public boolean add(E e){ }

        public E get(int index){   }

}

 6、泛型的通配符 <?>代表任意的数据类型

使用场景?

不知道使用什么类型来接收的时候,使用 ? 来表示未知通配符。

此时只能接收数据,而不能往集合中存储数据

使用方式:

不能创建对象使用,只能作为方法的参数使用

泛型通配符高级使用:不太常用

泛型的上限限定:? extends 类  如  ? extends E  //代表使用的泛型只能是E类型的子类/本身

泛型的下限限定:? super 类    如  ? super E      //代表使用的泛型只能是E类型的父类/本身 

 

集合数据结构:栈、队列、数组、链表和红黑树

:先进后出,出口与入口在一侧

队列:先进先出,出口与入口在集合的两侧

数组:查询快,增删慢。

数组的地址是连续的,通过数组的首地址可以找到数组,通过数组索引可以快速找到某一个元素。增删慢:因为长度是固定的,想要增删先要创建一个新的数组,把源数组复制过来。源数组会被垃圾回收。

链表:查询慢,增删快。

链表中的地址不是连续的,每次查询元素必须从头开始查询。

链表结构增删一个元素,对链表的整体结构没有影响。所以增删快。

单向链表:只有一条链子,不能保证元素的顺序(存储与取出的顺序可能不一致)。

双向链表:有两条链子,一条链子专门记录元素顺序,所以是一个有序的集合。

红黑树:

二叉树,分支不超过2个

排序树/查找树:在二叉树的基础上元素是有大小顺序的,左子树小,右子树大。

平衡树:左孩子与右孩子数量相等。查询速度非常快。

红黑树:趋近于平衡树,查询叶子节点的最大次数与最小次数不能超过2倍

红黑树的约束:了解

  1. 节点可以是红色的或者黑色的

  2. 根节点是黑色的

  3. 叶子节点(特指空节点)是黑色的

  4. 每个红色节点的子节点都是黑色的
  5. 任何一个节点到其每一个叶子节点的所有路径上黑色节点数相同

 

List集合:继承了Collection接口

特征:1、有序集合,存储和取出元素的顺序是一致的。

2、带索引

3、允许重复元素

特有的方法:

public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。

public E get(int index):返回集合中指定位置的元素。

public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。

public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。

List接口实现类:

ArrayList集合:底层结构是数组,所以是查询快,增删慢。也是基于多线程。

LinkedList集合:List的链表实现。多线程的。所以查询慢,增删快。包含了大量首尾元素的方法。使用linkedList集合特有的方法,就不能使用多态。因为多态是看不到子类特有的方法。

常用方法;

//添加
public void addFirst(E e)`:将指定元素插入此列表的开头。
public void addLast(E e)`:将指定元素添加到此列表的结尾。

//获取
public E getFirst()`:返回此列表的第一个元素。
public E getLast()`:返回此列表的最后一个元素。

//删除
public E removeFirst()`:移除并返回此列表的第一个元素。
public E removeLast()`:移除并返回此列表的最后一个元素

public E pop()`:从此列表所表示的堆栈处弹出一个元素。//相当于removeFirst();
public void push(E e)`:将元素推入此列表所表示的堆栈。
public boolean isEmpty()`:如果列表不包含元素,则返回true。

Vector集合:底层也是数组,同步的,单线程。jdk1.2+后被ArrayList取代。了解即可。

 

Set接口:externs Collection接口

特点:1、不允许存储重复的元素

2、没有索引,没有带索引的方法,也不能使用普通的for循环遍历

HashSet集合:实现了Set接口,除Set接口特点外:

一个无序的集合,存储元素和取出元素的顺序可能不一致

底层是一个哈希表结构(查询速度非常快)。

使用HashSet存储自定义元素:

存储元素必须重写hashCode方法和euals方法。

LinkedHashSet方法:extends HashSet集合

特点:有序的并且不允许重复

        底层是一个哈希表(数组+链表/红黑树)+链表(记录元素存储顺序),保证元素有序

扩展:哈希

哈希值:一个十进制整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,不是物理地址)Object类有一个方法,可以获取对象的哈希值     int   hashCode()返回对象的哈希码值

哈希表:哈希表=数组+红黑树  (提高查询速度)jdk1.8+后。

数组结构;把元素进行了分组(初始长度为16,链表/红黑树结构:把相同哈希值的元素链接到一起(链接到数组相同哈希值的下方)。

如果链表长度超过了8位,就会将链表转换为红黑树,提高查询速度。

set集合存储不重复原理:前提是重写对象的hashCode和equals方法。如String类,Integer类jdk已经重写好了

add方法先调用hashCode看哈希值有没有重复,没有就存储到集合,有就不存储,这就保证的只存储一次。若哈希值有冲突,会调用equals方法,对哈希值相同的元素进行比较,相同就不会存储第二个元素。

可变参数:当方法的参数列表的数据类型已经确定,但参数个数不确定时,就可以使用

格式:定义方法时使用

      修饰符   返回值类型    方法名(数据类型 ...  变量名){}

实现原理:

底层是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数。个数可以是0个(返回的是数组的地址)

注意事项:

一个方法参数,只能有一个可以变列表

一个方法的参数有多个,那么可变参数必须写在参数列表的未尾。

可变参数的特殊写法(终极):

Object  ... 变量名

 

Collections:集合的工具类,用来对集合进行操作

常用静态方法:

public static <T> boolean addAll(Collection<T> c, T... elements):往集合中添加一些元素。

public static void shuffle(List<?> list) 打乱顺序:打乱集合顺序。

public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。默认是升序

使用前提:被排序的集合,里面存储的元素,必须实现comparable,重写接口中的方法compareTo定义排序规则。

Comparable接口排序规则:

自己(this)  - (减号)  参数:升序,反之就是降序//为什么?

可以这样记忆,this看成是一个参照点,减去一个数,相当于参照点变小了,减去的数越大,那么参照点越小,所以是升序

反之,数-参照点,数越大,参照点也越大,相当于是降序。

public static <T> void sort(List<T> list,Comparator<? super T> ):将集合中元素按照指定规则排序。

Comparator与上一个的Comparable的区别:

Comparable:自己(this)和别人(传递进来的参数)比较,需要实现Comparable接口,重写比较规则 compareTo方法。

Compartor:相当于找一个第三方的裁判,比较两个 

排序规则:前面减后面就是升序

 

Map集合接口:里面有两个泛型<k,v>,<键,值>双列集合

键是唯一的,不允许重复,value可以重复

key与value数据类型可以相同也可以不同

key与value是一一对应的。

常用实现类:

java.util.HashMap<k,v> implements Map<k,v>接口

特点:

底层也是一个哈希表。与HashSet相同。

无序的集合,存储与取出元素的顺序有可能不一样

java.util.LinkedHashMap<k,v>  exteds HashMap<k,v>集合

特点:

底层是哈希表+链表,保证迭代的顺序

是一个有序的集合,存储与取出元素的顺序一致。

java.util.Hashtable<k,v>集合  implements Map<kv>接口

特点:

底层也是一个哈希表,是一个线程安全的集合,是单线程的集合速度慢。

HashMap底层也是一个哈希表,是一个线程不安全的集合,多线程,速度快

HashMap集合,可以存储null值,null键

Hshtable集合,不能存储null值,null键

Hashtable和Vector集合一样在jdk1.2之后被<HashMap,ArrayList>取代,但它的子类Properties依然在用,Proaperties集合是一个唯一和IO流相结合的集合

常用方法:

public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中。

   返回值:v

              存储键值对的时候,key不重复,返回值v是null

              key重复,会使用新的value替换map中重复的value,返回被替换的value值
public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元
值。

返回值v;

           key存在,v返回被删除的值

           key不存在,v返回null
public V get(Object key) 根据指定的键,在Map集合中获取对应的值。

     返回值 v:

            key存在,返回对应的value值 

            不存在,返回null

boolean containKey(object key);//判断集合中是否包含指定的键

        包含返回true,不包含返回false

 

//遍历
public Set<K> keySet() : 获取Map集合中所有的键,存储到Set集合中。

通过键找值方式:

1、使用Map集合中的方法keySet(),把Map集合所有的key取出来,存储到一个Set集合中

2、遍历set集合,获取Map集合中的每一个key

3、通过Map集合中的方法get(key),通过key 找到value


public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(取出来存储到Set集合)。
//Entry对象

Map.Entry<k,v>:在Map接口中有一个内部接口Entry

作用:当Map集合一创建,就会在Map集合中创建一个Entry对象,用来记录键与值(键值对对象)键与值的映射关系。

所以,使用Entry对象遍历步骤:

1、使用Map集合中的方法entrySet(),把Map集合中多个Entry对象取出来,放到一个set集合中。

2、遍历Set集合,获取每一个Entry对象

3、使用Entry对象中的方法getKey()和getValue()获取键与值

 

使用HashMap存储自定义类型键值:

     Map集合保证key值是唯一的

        作为key的元素,必须重写hashCode方法和equals方法,以保证key唯一。

 

jdk9的新特性:

     List接口,Set接口,Map接口,里面增加了一个静态方法of,可以给集合一次性添加多个元素

      static <E>  list<E> of(E... elements)

    使用前提:当集合中存储的元素的个数已经确定了,不再改变时使用

注意事项:

1、of方法只适用于List接口,Set接口,Map接口,不适用于接口的实现类

2、of 方法的返回值是一个不能改变的集合,集合不能再使用add,put方法添加元素会抛出异常

3、Set接口和Map接口在调用of方法的时候,不能有重复的元素,否则会抛出异常

 

idea:Debug追踪:

f8:逐行执行程序

f7:进入到方法中

shift+f8:跳出方法

f9:跳到下一个断点,如果没有,就结束程序

ctrl+f2:退出debug模式

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

guangod

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值