JAVA集合基础知识

集合

一.集合概述

​ 1、集合式一个容器,可以用来容纳其它类型的数据

​ 2、集合不能直接存储基本数据类型,集合也不能直接存储java对象,它存的是java对象的内存地址。如果存100,那也是java自动装箱Intiger之后再存的

注意:

​ 集合在java中本身是一个容器,是一个对象。

​ 集合中任何时候存储的都是“引用”。

二、集合的结构

​ 在java中集合分为两大类,一类是单个方式存储元素:他们的超级父类接口:java.util.Collection;

​ 一类是键值对的方式存储元素。。。。。。。。。java.util.Map;

Java集合Collection结构图,其中带○的都是接口,我们没办法直接用,用的最多的还是最下面一排的方法

JAVA集合基础知识_第1张图片

三、Collection 集合

1,概述

关于java.uit collection中常用的方法
1、collection中能存储什么元素?
	collection中可以存储object的所有子类型(集合中不能直接存储基本数据类型,也不能直接存储java对象,只是存储java对象的内存地址)

2、collection中长用的方法见下表,这里的方法是集合的公共方法,后面的所有集合都可以用下面的方法
返回值类型 方法 作用
boolean add(Object e) 向集合尾部添加元素(这里无论元素是否添加成功,都返回true)
int size() 判断集合的长度
void clear() 清空元素
boolean contains(Object e) 判断集合中是否包含元素e,返回true。false
boolean remove(Object e) 删除集合中的某个元素
boolean isEmpty() 判断集合是否为空
Iterator iterator() 获取一个迭代器,iterator()方法,返回Iterator对象
Object[] toArray() 调用这个方法可以把集合转换为数组
boolean addAll(Collection c) 将一个集合c中元素全部存储到当前集合中
1.2 关于Collection的 contains()方法 (remove()方法和这个一样)
contains()比较的时候底层调用了equals方法,如果我们自己创建的类没有重写equals方法,那么在两个new出来的对象比较的时候,会采用最底层的equals()比较两个对象的内存地址,就会返回false,
所以放在集合中的元素需要重写equals()方法。

关于

2、关于集合遍历/迭代专题 Iterator(迭代器)

​ 迭代器,用来获取集合中所有的数据(就是以前写的for循环),迭代器就相当于一个指针,一开始并没有指向第一个元素,可以理解为放在了第一个元素之前的位置

要想使用迭代器,首先必须获取集合对象的迭代器
Iterator it = c.iterator();
一定要注意:获取的迭代器,指向的是迭代器上面的那个集合,一旦集合结构在下面被改变了,就需要重新获取迭代器。不然再使用原迭代器会出异常,

迭代器是一个对象,对象中有三个常用的方法,这三个方法都是迭代对象 it 的方法

返回值类型 方法 作用
boolean hasNext() 如果仍有元素可以迭代,则返回true
Object next() next会让迭代器向下走一位,并且返回当前指向的元素
void remove() 从迭代器中删除当前元素

3、List接口

3.1、List存储元素的的点:
   有序:List集合中存储的原素有下标,从0开始,以1递增
   可重复:存过的数据还能再存进去
3.2、List中特有的方法(它继承了Collection,所以上面的Collection方法他都有)
返回值类型 方法 作用
Object get() 返回列表中指定位置的元素
int indexOf(Object o) 返回列表中第一次出现的指定元素的索引,如果没有,返回-1
int lastIndexOf(Object o) 返回列表中最后一次出现的指定元素的索引,如果没有,返回-1
Object remove(int index) 移出列表中指定位置的元素
Object set(int index, element) 用指定元素替换列表中指定位置的元素
void add(int index, element) 在列表的指定位置添加元素(重载方法)
因为 List 有下标,所以他可以使用for循环来遍历,不需要使用迭代器
for(int i = 0; i<list.size(); i++){
    System.out.println(list.get(i));
}

3.3、ArryList

ArrayList集合底层是Object类型的数组,怎么优化?
								尽可能少的扩容,因为扩容数组的效率比较低,建议在使用ArrayList集合的时								   候预估计元素的个数,给定一个初始化容量

ArrayList集合初始化容量是0,当添加第一个元素之后,会默认初识化10(看源码)
ArrayList在自动扩容时一次扩容1.5倍(看源码)

ArrayList的构造方法:

		List list = new ArrayList();//无参
        List list2 = new ArrayList(100);//初始化容量为100
        List list3 = new ArrayList(c);//将另一个集合传入新构造的集合中,这个传进来的也可以是Hashset

3.4、LinkedList(底层采用双向链表)

链表的优点:
		由于链表上的元素空间存储位置不连续,所以随机增删元素的时候不会有大量元素位移,因此随机增删效率高
链表的缺点:
		不能通过数学表达式计算出被查找元素的内存地址,每一次查找都是从头开始遍历,所以他的检索/查找效率低

3.5、vector

​ vector和ArrayList比较:

相同点:
	底层都是采用的数组结构
不同点:           vector                         ArrayList
	            是线程安全的					   是非线程安全的
	         初始化容量是10,每次扩容2倍           初始化0,添加第一个元素变为10,每次扩容1.5倍       
如何将一个线程不安全的Arraylist集合转换成一个线程安全的呢?
使用一个集合工具类:
		java.util.Collections;//这是集合工具类
		java.util.Collection;//这是集合接口
	用法:	
		List list = new ArrayList();//非线程安全的
        Collections.synchronizedList(list);//变成线程安全的

4、泛型机制

什么是泛型?有什么用?
	在集合中,我们可以存储任意的对象的引用,这样就会导致集合中的元素比较杂乱,导致我们在集合中循环/迭代取出的元素都是 Object 类。
	为了满足有时候我们集合中就只为了存储同一种类型的机制,java为我们提供了泛型机制,这样我们创建的集合就只能存储我们泛型指定的数据类型来存储,,在迭代取出元素的时候,也都是这个类型的元素(结合多态使用会更好)
怎么用?
		//创建一个Animal泛型的集合
        List<Animal> list = new ArrayList<Animal>();
        //这个表示迭代器迭代的是Animal类型
        Iterator<Animal> it = list.iterator();
JDK8之后,引入了自动类型推断机制。(又称为钻石表达式)
List<Animal> list = new ArrayList<>();//就是后面的集合会自动推断,ArrayList<>括号中可以不加Animal
自定义泛型可以吗?可以
public class DEMO <E>{    // E只是一个标识符,可以随便写什么,起作用的是<>但是下面要用的E的地方必须和上面写的内容保持一致,E可以用在方法的传参,也可以用在返回值类型的声明。
    public void doSome(E e){
        System.out.println(e);
    }
    public static void main(String[] args) {
        DEMO<String>  demo = new DEMO<>();//在new对象的时候在类的后面加上泛型,这就是自定义泛型
        demo.doSome("这里只能传String");
    }
}

5、forEach(增强for循环)

//以下是数组使用语法
        /*for(元素类型 变量名 :数组或集合){
            System.out.println(变量名);
        }*/
        int[] arr = {2,3,55,32,12,534};
        for(int date :arr){//date 就是数组中的元素(数组中的每一个元素)
            System.out.println(date);
        }
forEach有一个缺点:没有下标,在需要使用下标的时候不建议使用
//以下是集合使用语法
        List<String>  str = new ArrayList<>();
        for(String s : str){
            System.out.println(s);
        }

四、Map(是以键值对的方式存储的)

1、什么是Map?

1、Map和collection没有继承关系     
2、Map集合以key和value的方式 存储数据:键值对key和value都是引用数据类型,key和value都是存储对象的内存地址。key起到主导的地位,value是key的一个附属品
Java集合Map底层结构图

JAVA集合基础知识_第2张图片

Map中常用的一些方法
返回值类型 方法名 作用
void clear() 从此映射中移出所有映射关系
V put(K key, V value) 向map集合中添加键值对
Value get(Object key) 通过key返回其对应的value,没有则返回Null
V remove(Object key) 通过key删除键值对
boolean isEmpty() 判断集合是否为空
int size() 获取Map集合中键值对的个数
boolean containsValue(Object value) 判断是否包含某个Value
boolean containsKey(Object key) 判断是否包含某个key
Set keySet() 获取Map集合所有的key,返回的是一个Set集合
Collection values() 获取Map集合所有的value,返回的是一个Collection集合
Set> entrySet() 将Map集合转换成Set集合
Set>详解:
		假设现在有一个Map1集合:    key       value
								1		zhangsan
                                2		lisi
                                3		wangwu
         调用转换方法: Set set1 = Map.entrySet();  返回的是一个Set集合,里面存储:1=zhangsan  2=lisi   3=wangwu

Map方法的运用

 //创建Map对象
        Map<Integer,String> map = new HashMap<>();
        //向Map集合中添加键值对
        map.put(1,"zhangsan");//在这里1仍然会自动装箱
        map.put(2,"lisi");
        map.put(3,"wangwu");
        //通过key获取value
        String value = map.get(2);
        //获取键值对的数量
        int size = map.size();
        //通过key删除键值对
        map.remove(2);
        //判断是否包含某个key   注意:contains方法比较的时候,底层都是调用的equals方法进行比较的,所以我们在存自己创建的对象时一定要重写equals方法
        boolean b1 = map.containsKey(1);
        //判断是否包含某个value
        boolean b2 = map.containsValue("wangwu");
        //清空Map集合
        map.clear();
		//判断是否为空
        boolean b3 = map.isEmpty();
		//获取Map集合中所有的value
        Collection<String> values = map.values();

Map集合的遍历(重要)

//第一种,获取Map集合所有的key,通过遍历key,来遍历value
		//获取所有的key,所有的key是一个Set集合
        Set<Integer> keys = map.keySet();
        //通过迭代器,遍历key,通过key获取value                             通过foreach,遍历key,通过key获取value 
        Iterator<Integer> it = keys.iterator();							for(Integer  key:keys){
        while(it.hasNext()){												String value = map.get(key);
            Integer key = it.next();									}
            String value = map.get(key);
        }

//第二种方式:直接把Map集合全部转换成Set集合,Set集合中元素的类型是Map.Entry();这种方式效率比较高
        Set<Map.Entry<Integer,String>> set = map.entrySet();
        //迭代器遍历Set集合,每一次取出一个Node								foreach循环遍历
        Iterator<Map.Entry<Integer,String>> it = set.iterator();		for(Map.Entry<Integer,String> node :set){
        while(it.hasNext()){												Integer key = node.getKey();
            Map.Entry<Integer,String> node = it.next();						String value = node.getValue();
            Integer key = node.getKey();								}
            String value = node.getValue();
        }

2、HashMap集合

HashMap结构底层是一个哈希表/散列表的数据结构,
什么是哈希表:
		 哈希表底层实际上是一个一维数组,这个数组中的每个元素都是一个单向链表。它充分发挥了数组和单向链表的优势(底层结构有点像珠珠帘)	 

3、必须要掌握 map.put()和map.get()

​ 底层原理就像查字典

重点:
	放在HaashMap集合key部分的元素,以及放在HashSet集合中的元素,需要同时重写hashCode和equals方法,如果equals方法重写了,hashCode方法必须重写,并且如果equals方法返回值是true,hashCode方法返回值也必须是true。
	重写直接用idea生成就行了,但是要注意一定要同时生成。
	HashMap集合的默认初始画容量是16,默认加载因子是 0.75(当HashMap集合底层数组的容量达到75%的时候,数组开始扩容)
	HashMap集合初始化容量必须是2的倍数,这也是官方推荐的,这是因为达到散列分布均匀,为了提高HashMap集合的存储效率,所必须的。

4、HashMap和HashTable的区别

	HashMap是非线程安全的,默认初始画容量是16,默认加载因子是 0.75,扩容之后的容量X2,它的key和value可以存储null
	
	HashTable是线程安全的,默认初始画容量是11,默认加载因子是 0.75,扩容之后的容量X2+1,它的key和value不能存储null
Properitise属性类对象的相关方法
Properitise是一个Map集合,继承HashTable, Properitise的 key 和 value 都是 String 类型的
Properitise被称为属性类对象,是线程安全的
需要掌握两个方法:
			存:pro.setProperty("username","root");
			取:String s =pro.getProperty("username");

5、TreeSet集合

概述
1、TreeSet集合底层其实是一个TreeMap,TreeMap底层其实是一个二叉树
2、放到TreeSet集合中的元素,等于放到了treeMasp集合的key部分
3、TreeSet集合中的元素,无序不可重复,但是可以通过元素的大小顺序自动排序
对自定义的类型来说,TreeSet可以排序吗?
	不仅无法排序,而且还会出异常。因为您自定义的类,没有申明排序的规则。
(重点)放在TreeSet集合中的元素需要实现java.lang.Comparable 接口,并且实现compareTo方法。equals方法可以不写

perty(“username”);




#### 5、TreeSet集合

##### 		概述

1、TreeSet集合底层其实是一个TreeMap,TreeMap底层其实是一个二叉树
2、放到TreeSet集合中的元素,等于放到了treeMasp集合的key部分
3、TreeSet集合中的元素,无序不可重复,但是可以通过元素的大小顺序自动排序


##### 		对自定义的类型来说,TreeSet可以排序吗?

不仅无法排序,而且还会出异常。因为您自定义的类,没有申明排序的规则。

##### 	(重点)放在TreeSet集合中的元素需要实现java.lang.Comparable 接口,并且实现compareTo方法。equals方法可以不写 



#### 6、自平衡二叉树

你可能感兴趣的:(java)