为什么要有集合:
我们直到在Java万事万物皆对象,面向对象的语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,我们想办法把多个对象存储起来,进行集中化操作。而集合可以动态化的进行对象存储,正满足我们想要的。
数组在存储数据方面是有弊端的:数组初始化之后,长度就不可以 改变了,不便于扩展;数组提供的属性和方法很少效率不高;存储数据的特点单一。【同时也是数组的一大优点】。
集合的分类:
集合可以分为两大体系: Collection体系和Map体系 。而Collection接口的两个实现类分别是List和Set,Map接口只有一个实现类Map类。
- List集合的特点:元素有序,可以重复。
- Set集合的特点:元素无序,不可以重复。
- Map集合的特点:使用双列数据:key-value键值对:key的值是无序的不可以重复的,所以用Set集合来进行存储。value值存储是无序的可以重复的可以使用Colletion来进行存储的。一个键值对构成了一个Entrry对象
集合中常用的方法:
以为Collection体系为例:
@Test
public void list(){
ArrayList<Object> objects = new ArrayList<>();
LinkedList<Object> objects1 = new LinkedList<>();
objects.add(123); //集合是用来存储对象的为什么还可以输入普通的类型 原因是;进行可以对封装性的运用
objects.add(852);
objects.add(new erroer());
objects.add("小张");
objects.add(false);
System.out.println(objects);
System.out.println(objects.contains(123)); //是用来进行判断集合中是不是有123这个元素
System.out.println(objects.contains(new String("小张")));//可以看出判断的是内容不是地址
List<Integer> integers = Arrays.asList(123, 852);//是进行将数组转化为集合 返回值是List
System.out.println(objects.contains(integers)); //contains方法同时可以进行比较两个集合是不是相等
System.out.println(objects.remove("小张")); //是进行按照集合中的值来进行删除集合之中的元素
System.out.println(objects.remove(0)); //是进行按照集合中的下角标来进行删除集合中的元素 返回值是删除的元素的值
System.out.println(objects.removeAll(integers)); //是从一个集合中删除另一个集合中的所有元素 参数必须是一个collection类型的变量
System.out.println(objects.retainAll(integers)); //是用来删除两个集合之间不是共用的元素只保留两个集合之间共用的元素
System.out.println(objects);
System.out.println(objects.toArray()); //是将集合转换为数组 但是转成的数组是Object【】类型的数组
}
集合的遍历:
集合遍历的三种方式:
- 第一种普通的for循环(并不常用,不进行举例)
- 第二种增强for循环
- 第三种迭代器
以迭代器形式进行遍历:
@Test
public void sjds(){
ArrayList<Object> objects = new ArrayList<>();//先进行默认的创建长度为10的object[]数组
objects.add(123);
objects.add(456);
objects.add(789);
objects.add(456);
objects.add(456);
Iterator<Object> iterator = objects.iterator();//创建迭代器
while (iterator.hasNext()){//是进行判断集合中是不是还有元素 并不会导致指针的下移
System.out.println(iterator.next());// next才是进行指针的移动每次执行向下移动一次
}
while (iterator.hasNext()){ //第二次循环并不会输出数据原因是 上一次循环迭代器的指针已经到底部了所以不会返回数据
System.out.println(iterator.next());
}
}
注意第二次遍历并不会输出数据是因为迭代器指针已经指向了集合的最底部,而迭代器的指针并不会自动的回到集合的顶端,如果想二次遍历可以重新创建一个迭代器对象。
使用增强for循环进行遍历:
@Test
public void shdj(){
ArrayList<Object> objects = new ArrayList<>();
objects.add(123);
objects.add(456);
objects.add(789);
objects.add(456);
objects.add(456);
for (Object o:objects) {
System.out.println(o);
}
}
List集合具体介绍:
List接口有三个具体的实现类ArrayList、LinkedList、Vector
使用三者 创建List集合的对比:
相同点 | 都是实现了List接口,存储数据的特点是相同的,都是无序的可以重复的。 |
不同点 | ArrList:,是主要的实现类、是线程不安全的、执行效率高、底层使用的是Objet【】数组进行存储。 LinkedList,底层使用链表结构来存储数据,在频繁的删除,插入操作中效率较高。 Vector,不常用 |
set集合具体介绍
Set接口的实现类:HashSet、LinedHashset
比较:
相同点 | 都是实现了Set的接口,数据的存储结构是一样的,有序不可重复。 |
不同点 | HashSet:作为主要的实现类,线程不安全,可以存储null.底层使用数组+链表。 LinedHashset;遍历内部数据时,可以按添加的顺序来进行遍历。 TreeSet: 底层的存储结构是按照二叉树进行存储的,【限制:存入的对象必须是同一个类new的对象,然后利用这些对象的某些属性进行排序】 |
set的无序性并不是指随机性,set存储数据的位置是依赖哈希表来进行的,通过对象的属性值来确定哈希值,从而确定在数组的存放位置,如果两个对象的哈希值一样的话会以链表的形式进行存储 这两个值。
Map集合具体介绍
Map接口的实现类:HashMap 、TreeMap、Hashtable
三个实现类的介绍
HashMap | 作为Map的主要实现类、线程不安全效率高、可以存储null,底层使用数组+链表+红黑树 |
TreeMap | 可以保证读取数据的时候是按照 书写的顺序来进行读取,在频繁的读取操作中效率高于HashMap |
Hashtable | 使用率较低 |
对Map 中键值对的理解:
使用时可以根据key的值来查找value的值
key:key的值是无序的不可以重复的,所以用Set集合来进行存储。
value值:存储是无序的可以重复的可以使用Colletion来进行存储的。一个键值对构成了一个Entrry对象。
map的基本底层和set的底层相似【当然还是有区别的】
要往一个集合中添加实体类对象,要进行 重写实体类中的equals()方法 和hashCode() 的方法。
Map接口的常用方法:
@Test
public void sjkdk(){
HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
HashMap<Object, Object> objectObjectHashMap1 = new HashMap<>();
objectObjectHashMap.put(null,null); //向Map集合中添加数据 可以是null
objectObjectHashMap.put("AAA",123);
objectObjectHashMap1.put("BBB",456);
objectObjectHashMap1.put("CCC",456);
objectObjectHashMap.putAll(objectObjectHashMap1);//是将一个集合中的元素添加到另一个集合中
objectObjectHashMap.remove("AAA");//是通过kay的值进行删除集合中的值
objectObjectHashMap.remove("AAA",123);//也可以通过kay-value来进行删除
objectObjectHashMap1.clear();//是将Map集合中的元素进行清空,但并不是删除map集合
System.out.println(objectObjectHashMap1.get("CCC"));//并返回value的值
objectObjectHashMap1.containsKey("BBB");//通过key的值进行查找
objectObjectHashMap1.size(); //判断集合中有多少键值对
objectObjectHashMap1.equals(objectObjectHashMap);//判断两个集合是不是相等 对顺序没有要求
}
Map集合的遍历:
使用迭代器:
@Test
public void slkkl(){
HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
objectObjectHashMap.put("AAA",123);
objectObjectHashMap.put("BBB",456);
objectObjectHashMap.put("CCC",789);
Iterator<Object> iterator = objectObjectHashMap.keySet().iterator();
while(iterator.hasNext()){
System.out.println(objectObjectHashMap.get(iterator.next()));
}
}
方式二;{还有很多的形式}
Set<Map.Entry<Object, Object>> entries = objectObjectHashMap1.entrySet();// 是用来获取Enter
Iterator<Map.Entry<Object, Object>> iterator1 = entries.iterator(); // Enter 实际上也是Map 可以进行创建迭代器
while (iterator1.hasNext()){
Map.Entry<Object, Object> next = iterator1.next(); //迭代器的 原本的返回值是 Object 类型 强制转换到Enter才能
//进行操作Enter类中的方法
next.getKey();
next.getValue();
}
使用增强for循环:
@Test
public void slkkl(){
HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
objectObjectHashMap.put("AAA",123);
objectObjectHashMap.put("BBB",456);
objectObjectHashMap.put("CCC",789);
for ( Object o : objectObjectHashMap.keySet() ) {
System.out.println(objectObjectHashMap.get(o));
}
}
方式二:{还有其他的很多方式}
Collection<Object> values = objectObjectHashMap1.values();
for (Object obj:values
) {
System.out.println(obj);
}