数组和集合基础

数组和集合的特点

1.数组的特点

  1. 数组一旦被定义长度不可以发生变化
  2. 数组种的元素有索引
  3. 数组可以存储基本数据类型和应引用数据类型
  4. 数组中的元素类型必须一致

数组初始化

动态初始化:数据类型[] 数组名 = new 数组类型[数组长度]
例:int[] arr = new int[5];

静态初始化:数据类型[] 数组名 = new 数组类型[]{元素1,元素2,…}
例:int[] arr = new int[]{1,2,3};
简化格式:数据类型[] 数组名 = {元素1,元素2,…}
例:int[] arr = {1,2,3};

2.集合的特点

  1. 集合的长度可以发生改变
  2. 集合只能用于存储引用数据类型(基本数据类型都有相应的包装类)

2.1 单列集合Collection:

  • 单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是java.util.List和java.util.Set。其中,List的特点是元素有序、元素可重复。Set的特点是元素无序,而且不可重复。List接口的主要实现类有java.util.ArrayList和java.util.LinkedList,Set接口的主要实现类有java.util.HashSet和java.util.TreeSet。

Iterator接口:

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

Iterator接口的常用方法如下:

  • public E next():返回迭代的下一个元素。
  • public boolean hasNext():如果仍有元素可以迭代,则返回 true

增强for

  • 增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。
    单列集合

注意

1.数组转换成List之后不能进行add和remove,会报错

String[] array = {"a","b","c"};
List<String> listArray = Arrays.asList(array);

Arrays源码里发现这里new了一个ArrayList的集合,但是这不是ArrayList类,这是Arrays里的一个静态的内部类。此内部类并没有add和remove方法,所以如果此时调用add或者remove方法则会报错。
解决方法:将之前的对象放入一个新的ArrayList对象,再对新的ArrayList对象进行操作

List<String> newStrings = new ArrayList<String>(listArray);

2.HashSet集合存储数据的结构(哈希表)

  • 在JDK1.8之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。
  • 而JDK1.8中,哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

Collections

  • java.utils.Collections是集合工具类,用来对集合进行操作。部分方法如下:

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

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

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

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

说到排序了,简单的说就是两个对象之间比较大小,那么在JAVA中提供了两种比较实现的方式,一种是比较死板的采用java.lang.Comparable接口去实现,一种是灵活的当我需要做排序的时候在去选择的java.util.Comparator接口完成。

  • public int compare(String o1, String o2):比较其两个参数的顺序。
    两个对象比较的结果有三种:大于,等于,小于。
    如果要按照升序排序,
    则o1 小于o2,返回(负数),相等返回0,01大于02返回(正数)
    如果要按照降序排序
    则o1 小于o2,返回(正数),相等返回0,01大于02返回(负数)
		 //排序方法  按照第一个单词的降序
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o2.charAt(0) - o1.charAt(0);
            }
        });

2.2 双列集合Map

  • HashMap<K,V>:存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
    HashMap是非线程安全的,只是用于单线程环境下,多线程环境下可以采用concurrent并发包下的concurrentHashMap。

  • LinkedHashMap<K,V>:HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。

  • Hashtable<K,V>:同样是基于哈希表实现的,同样每个元素是一个key-value对,其内部也是通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长。

HashTable 和 HashMap 的实现原理几乎一样,差别无非是
1.HashTable 不允许 key 和 value 为null;
2.HashTable 是线程安全的。
但是 HashTable 线程安全的策略实现代价却太大了,简单粗暴,get/put 所有相关操作都是 synchronized 的,这相当于给整个哈希表加了一把大锁,多线程访问时候,只要有一个线程访问或操作该对象,那其他线程只能阻塞,相当于将所有的操作串行化,在竞争激烈的并发场景中性能就会非常差。

Map

Propertise类

它是一个双列集合,它的键值对都是String类型
常用方法

  • Object setProperty(String key, String value)
    添加/修改,键和值
  • String getProperty(String key)
    根据键获取值
  • void load(InputStream inStream)
    把文件中的键值对,读取到Propertise中,文件中键值对的格式必须是key=value
  • void store(OutputStream out, String comment)
    把propertise集合中的键值对保存到文件中,参数comment为写入的注释
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值