Java集合入门

集合的框架概述

1.集合,数组都是对多个数据进行存储操作的结构,简称Java容器
说明:此时的存储,主要指内存层面的存储,不涉及持久性的存储
2.数组在存储多个数据方面的特点:
 		> 一旦初始化以后,长度就确定了
 		> 数组一旦定义好,其元素类型也就确定了
3.数组在存储多个数据方面的缺点
		>  一旦初始化后长度不可修改
		>  数组中提供的方法非常有限,且效率不高
		>  数组存储数据的特点:有序,可重复。对于无须,不可重复的需求不能满足

在这里插入图片描述

Collection

在这里插入图片描述

Collection常用方法

    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(): 把集合中的元素,存储到数组中。

注意:向Collection接口的实现类的对象中添加数据obj时,要求obj所在类重写equals方法。

Iterator迭代器

1.集合每次调用iterator方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素前。
2.内部定义了remove方法,可以在遍历的时候直接删除集合中的元素,区别于集合直接调用的remove()
public static void main(String[] args) {
      
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(789);
        
		Iterator iterator = coll.iterator();        //迭代器
        while(iterator.hasNext())                   //迭代器运用
        {
            Object ob = iterator.next();
            if(ob.equals(123))
                iterator.remove();
        }
        
        Iterator iterator1 = coll.iterator();       //遍历方式一
        while(iterator1.hasNext())
        {
            System.out.println(iterator1.next());
        }

        for (Object o:coll      //遍历方式二
             ) {
            System.out.println(o);
        }
    }

List

在这里插入图片描述

ArrayList,LinkedList源码分析

ArrayList分析:jdk7
	ArrayList list = new ArrayList();	底层创建长度为10 的Object[]数组elementDate
	list.add(123);		elementDate[0] = new Integer(123);
	...
	list.add(123);		如果此次添加导致底层的elementDate数组容量不够则扩容
	默认情况下,扩容为原来的1.5倍;同时需要将原有数组中的数据复制到新的数组中
-----------------------------------------------------------------------------------------
jdk8中ArrayList中的变化:
ArrayList list = new ArrayList();		底层数组初始化,并未创建长度
list.add(123)		第一次调用add才创建了长度为10 的数组
LinkedList的分析:
LinkedList list	= new LinkedList();		内部声明了Node类型的first和last属性并赋为null
list.add(123);		将123封装到Node中,创建了Node对象

ArrayList,LinkList,Vector三者异同

同:三者都是实现了List接口,存储数据的特点相同:有序,可重复
异:ArrayList:线程不安全,效率高,底层使用Object[] elementDate储存
	LinkedList:底层使用双向链表储存
	Vector:线程安全,效率低,底层使用Object[] elementDate储存

List常用方法

void add​(int index, E element)	将指定元素插入此列表中的指定位置
boolean	addAll​(int index,Collection else)	从index位置开始将else中所有的元素插入
Object get(int index)  	获取指定index位置的元素
int indexOf​(Object o)	返回此列表中第一次出现的指定元素的下标,如果此列表不包含该元素,则返回-1。
int lastIndexOf​(Object o)	返回此列表中指定元素最后一次出现的索引,如果此列表不包含该元素,则返回-1。
Object remove​(int index)	删除此列表中指定位置的元素。
Object	set​(int index, E element)	使用指定的元素替换此列表中指定位置的元素
asList(T[] t)	数组转 List
toArray()	List 转数组

Set

在这里插入图片描述

Set:储存无序的,不可重复的数据
以HashSet举例
1.无序性:无序性不等于随机性。储存的数据在底层数组中并非按照索引 的顺序添加,而是根据哈希值
2.不可重复性:保证添加的元素按照equals()判断时,不能返回true,即相同元素只能添加一个

注意:向Set接口的实现类的对象中添加数据obj时,要求obj所在类重写equals方法和HashCode方法。

HashSet

HashSet底层其实是用HashMap实现存储的

具体实现唯一性的比较过程:存储元素首先会使用hash()算法函数生成一个int类型hashCode散列值,然后已经的所存储的元素的hashCode值比较,如果hashCode不相等,则所存储的两个对象一定不相等,此时存储当前的新的hashCode值处的元素对象;如果hashCode相等,存储元素的对象还是不一定相等,此时会调用equals()方法判断两个对象的内容是否相等,如果内容相等,那么就是同一个对象,无需存储;如果比较的内容不相等,那么就是不同的对象,就该存储了,此时就要采用哈希的解决地址冲突算法,在当前hashCode值处类似一个新的链表, 在同一个hashCode值的后面存储存储不同的对象,这样就保证了元素的唯一性。

Set的实现类的集合对象中不能够有重复元素,HashSet也一样他是使用了一种标识来确定元素的不重复,HashSet用一种算法来保证HashSet中的元素是不重复的, HashSet采用哈希算法,底层用数组存储数据。默认初始化容量16,加载因子0.75。达到16*0.75后扩容(2倍)

Object类中的hashCode()的方法是所有子类都会继承这个方法,这个方法会用Hash算法算出一个Hash(哈希)码值返回,HashSet会用Hash码值去和数组长度取模, 模(这个模就是对象要存放在数组中的位置)相同时才会判断数组中的元素和要加入的对象的内容是否相同,如果不同才会添加进去。

LinkedHashSet


作为HashSet的子类,遍历其内部数据时,可以按照添加的顺序遍历

TreeSet


1.向TreeSet中添加的数据,要求是相同类的对象
2.俩种排序方式:自然排序(实现Comparable接口)和定制排序(Comparator)
3.对象是否相同的标准不再是equals而是俩种排序

Map

在这里插入图片描述

在这里插入图片描述

Map结构的理解:
1.Map中的key:无序的,不可重复的,使用Set存储所有的key
------>所在的类要重写equals,hashcode
2.Map中的values:无序的,可重复的,使用Collection存储所有的values
------>所在的类要重写equals
3.Map中的entry:无序的,不可出发点,使用Set存储所有的entry

HashMap


HashMap的底层原理:
jdk7
HashMap map = new HashMap();
在实例化后,底层创建了长度为16的一维数组Entry[] table
...经历多次put...
map.put(xxx,xxx);
首先,调用key所在类的hashcode计算key的哈希值,此哈希值经历算法计算后,得到Entry数组中存放的位置。
如果此位置为空,此时key-values添加成功 ---------情况1
如果此位置不为空,(意味着此位置存在一个或多个数据(以链表的形式存在)),比较key和已经存储的数据的哈希值:
		如果key的哈希值与已经存在的数据的哈希值都不同,则此时key-values添加成功 --------情况2
		如果key的哈希值和已经存在的某个数据的哈希值相同,继续比较(调用key所在的类的equals)
					如果不相同,则此时key-values添加成功 --------情况3
					如果相同,则将原来的values替换成新的values

补充:情况2,情况3的数据以链表形式存储

当数组达到:默认容量(16)*默认加载因子(0.75)= 扩容临界值(12)后数组扩容,扩容到原来的2倍
------------------------------------------------------------------------------------------------
jdk8
1.new 的时候仅声明,put的时候才创建长度为16的数组
2.底层为Node而非Entry
3.当数组某一个索引位置上的元素以链表形式存在的数据个数 > 8个 且当前数组长度 > 64时,
此时此索引上的所有数据改为用红黑树存储

在这里插入图片描述

遍历HashMap的四种方式

● keys() 获取所有 key,values() 获取所有 value

HashMap map = new HashMap();
map.put(1,1);
map.put(2,2);
map.put(3,3);
map.put(4,4);
map.put(5,5);
map.put(6,6);
 
Set<Integer> keys = map.keySet();
for (Integer key : keys) {
    System.out.println(key);
}
Collection<Integer> values = map.values();
for (Integer value : values) {
    System.out.println(value);
}

● 使用 Iterator 迭代器迭代

Iterator iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
    Map.Entry<Integer, Integer> mapEntry = (Map.Entry<Integer, Integer>) iterator.next();
    System.out.println(mapEntry.getKey() + " === " + mapEntry.getValue());
}

● 使用 get 方式

Set<Integer> keySet = map.keySet();
for(Integer item: keySet) {
    System.out.println( item + "====" + map.get(item));
}

● jdk1.8 后使用 Map 接口中的默认方法

map.forEach((key,value) -> {
    System.out.println(key + "========" + value);
});

HashMap常用方法

Object put(Object key,Object values):插入/更新
void putAll(Map m):将m中的全部元素存放到现有的map中
Object 	remove(Object key):将指定key的key-values对删除
void clear():清空当前map所有数据

LinkedHashMap

TreeMap

Properties

public class MyProp {
    public static void main(String[] args) throws IOException {
        Properties prop = new Properties();
        FileReader fileReader =
                new FileReader(new File("Day12\\prop.properties"));
        //读取
        prop.load(fileReader);
        fileReader.close();
        System.out.println(prop);
        System.out.println("===============");
        Set<String> keys = prop.stringPropertyNames();
        for (String key : keys) {
            String value = prop.getProperty(key);
            System.out.print(key+"\t"+value);
        }
    }

Collections

Collections与Collection的不同

Collections是工具类,不能被实例化。
而Collection是集合接口,包括List,Set。

Collections常用方法

public class CollectionsTest {

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(34);
        list.add(55);
        list.add(56);
        list.add(89);
        list.add(12);
        list.add(23);
        list.add(126);
        System.out.println(list);

        //对集合进行排序
        Collections.sort(list);
        System.out.println(list);

        //对集合进行随机排序
        Collections.shuffle(list);
        System.out.println(list);

        //获取集合最大值、最小值
        int max = Collections.max(list);
        int min = Collections.min(list);
        System.out.println("Max:" + max + " Min: " + min);

        List<String> list2 = Arrays.asList("Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday".split(","));
        System.out.println(list2);

        //查找集合指定元素,返回元素所在索引
        //若元素不存在,n表示该元素最有可能存在的位置索引
        int index1 = Collections.binarySearch(list2, "Thursday");
        int index2 = Collections.binarySearch(list2, "TTTTTT");
        System.out.println(index1);
        int n = -index2 - 1;

        //查找子串在集合中首次出现的位置
        List<String> subList = Arrays.asList("Friday,Saturday".split(","));
        int index3 = Collections.indexOfSubList(list2, subList);
        System.out.println(index3);
        int index4 = Collections.lastIndexOfSubList(list2, subList);
        System.out.println(index4);

        //替换集合中指定的元素,若元素存在返回true,否则返回false
        boolean flag = Collections.replaceAll(list2, "Sunday", "tttttt");
        System.out.println(flag);
        System.out.println(list2);

        //反转集合中的元素的顺序
        Collections.reverse(list2);
        System.out.println(list2);

        //集合中的元素向后移动k位置,后面的元素出现在集合开始的位置
        Collections.rotate(list2, 3);
        System.out.println(list2);

        //将集合list3中的元素复制到list2中,并覆盖相应索引位置的元素
        List<String> list3 = Arrays.asList("copy1,copy2,copy3".split(","));
        Collections.copy(list2, list3);
        System.out.println(list2);

        //交换集合中指定元素的位置
        Collections.swap(list2, 0, 3);
        System.out.println(list2);

        //替换集合中的所有元素,用对象object
        Collections.fill(list2, "替换");
        System.out.println(list2);

        //生成一个指定大小与内容的集合
        List<String> list4 = Collections.nCopies(5, "哈哈");
        System.out.println(list4);

        //为集合生成一个Enumeration
        List<String> list5 = Arrays.asList("I love my country!".split(" "));
        System.out.println(list5);
        Enumeration<String> e = Collections.enumeration(list5);
        while (e.hasMoreElements()) {
            System.out.println(e.nextElement());
        }
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值