基础(二)集合"/>
Java基础(二)集合
集合Collection
集合与数组的区别
相同点:
集合和数组都能存储数据
不同点:
数组:
(1)可以存储基本数据类型
(2)可以存储引用数据类型
(3)是一个定长的容器
集合:
(1)只能存储引用数据类型
(2)如果存储基本数据类型,只能存储对应的包装类,因为有自动装箱,所以看起来可以直接存储,但是实际存储的类型是包装类
(3)集合可以认为是一个可以伸缩的容器
基本数据类型:boolean、char、byte、short、int、long、float、double
引用数据类型:除了基本数据类型都是引用数据类型
单列集合
单列集合的每个元素都是单独的个体,存储单个元素。
1、Collection是单列集合的顶层接口,定义了所有单列集合的共有的内容,jdk不提供此接口的任何直接实现,提供了更具体的子接口(List、Set)
2、创建Collection集合对象
Collection接口,不能直接创建对象,需要找一个例如:ArrayList创建对象
多态的方式:接口类型的引用指向实现类对象 Collection c = new ArrayList();
3、Collection集合的方法
add(Object o):添加元素,有返回值,返回值为布尔类型
remove(Object o):删除元素,有返回值,返回值为布尔类型
clear():清空集合中的元素 void 没有返回值
contains(Object o):判断集合中是否存在指定的元素,返回值布尔类型
isEmpty():判断集合是否为空 空不是null 空返回true,非空返回false(null是连对象也没有,空是对象中没有任何内容)
size():返回集合中元素的个数,集合的长度
toArray():将集合存储的内容转存到数组中 返回值Object[]
单列集合的遍历
迭代器遍历
1、迭代:更新换代
2、迭代器:专门针对单列集合进行遍历的对象成为迭代器,是单列集合专用的遍历方式,迭代器也可以边路数组(增强for循环)。
3、获取集合迭代器的方式:
Iterator iterator();返回此集合中元素的迭代器,通过集合Iterator()获取。
Collection c = new ArrayList();
Iterator it = c.iterator();
4、Iterator的常用方法:
boolean hasNext():判断当前位置是否有元素可以被取出
Object next():获取当前位置的元素,将迭代器对象指向的位置向下移动一格
void remove():删除迭代器对象当前指向的元素
Collection c = new ArrayList();c.add("一");c.add("二");c.add("三");//增强for循环System.out.println("增强for循环");for (Object o : c) {System.out.println(o);}//迭代器遍历System.out.println("迭代器遍历");Iterator it = c.iterator();//获取集合迭代器while (it.hasNext()){//boolean类型,判断当前位置是否有元素可以取出Object next = it.next();//获取当前位置元素,并将指针向下移动一格it.remove();//删除当前指针指向的元素System.out.println(next);}//迭代器删除元素后再遍历System.out.println("remove之后");for (Object o : c) {System.out.println(o);}
有序的单列集合List
1、List集合是Collection接口的子接口,其下有常用的实现类ArrayList,Vector,LinkedList
2、List集合的特点:
有序:元素存入的顺序和取出的顺序一致
有索引:每个元素都有自己的索引,从0开始到集合长度-1
元素值可以重复,即使是值相同的几个元素,索引也各不相同
3、List集合的特有的方法:
add(int index,Object o):在集合中指定的位置插入指定的元素
remove(int index):删除指定索引的元素,返回值就是被删除的元素
removeAll(Object o):删除集合中所有的o元素
set(int index,Object o):修改指定索引的元素,返回被修改的元素
get(int index):返回指定索引位置的元素
4、Collection下有个size()方法,可以获取元素个数,有元素个数就相当于有索引范围,也就意味着可以通过集合的size()方法获取索引范围,根据索引通过get方法,获取到每一个元素
List l = new ArrayList();l.add(1);l.add(1);l.add(4);l.add(5);l.add(1);l.add(4);for (Object o : l) {System.out.print(o+"\t");}System.out.println();//在指定位置插入元素System.out.println("在索引1增加元素9");l.add(1,9);for (Object o : l) {System.out.print(o+"\t");}//删除指定位置的元素System.out.println();System.out.println("删除索引4,并返回删除的值");Object remove = l.remove(4);System.out.println(remove);for (Object o : l) {System.out.print(o+"\t");}//修改指定位置的元素System.out.println();System.out.println("将索引1修改为5,并返回被修改的元素");Object set = l.set(1, 5);System.out.println(set);for (Object o : l) {System.out.print(o+"\t");}
无序单列集合Set
1、Set是一个接口,接口中的方法都是继承Collection。
2、无序:没有任何前后的分别,存入的顺序和取出的顺序不一定一致(Set有自己存放元素位置的规则,并不是常见的先来后到或其他规则。)
*无序不是随机,它对排序有自己的理解,一般不是写入的顺序
3、没有索引:集合中没有任何位置,元素也就没有索引的概念
4、不能重复:没有任何索引,相同元素就没有任何区别,所以不能重复
5、Set常用的实现类:HashSet(常用),TreeSet(可以自定义元素存储先后顺序的规则,一个实现类)
6、Set集合的遍历方式:迭代器和增强for循环
HashSet
1、该类型没有特有的方法,相同的元素只存储一份,通过哈希值存储。如果哈希值不同,则直接存储,如果哈希值相同,则比较属性值。
2、存储自定义类的时候,默认是可以存储相同元素的,如果想要保证自定义元素存储的唯一性,需要重写hashCode和equals。
3、元素存储的过程:
(1)使用add方法添加元素时,会调用一次hashCode方法产生一个数字,这个数字就是哈希值。
(2)在集合中查找是否有相同哈希值的元素。
(3)如果没有相同哈希值的元素,则直接存储。
(4)如果有,则调用equals方法判断两个对象中的属性值,若相同则不能存储。(不同属性值有极小可能会计算出相同的哈希值)
(5)如果equals方法返回false,意味着属性值不同(但哈希值相同),可以存储
(6)如果equals方法返回true,意味着属性值也相同(哈希值相同),不能存储。
4、如果想要在Set集合中保证自定义元素的唯一性,需要重写hashCode和equals方法。
以下在Set集合中存入几个数字
Set s = new HashSet();s.add("5");s.add("2");s.add("4");s.add("5");s.add("1");s.add("4");s.add("3");s.add("3");for (Object o : s) {System.out.print(o+"\t");}
最后遍历集合得到的结果是:
若存储的是自定义类:
Set s2 = new HashSet();s2.add(new Person("张三",18));s2.add(new Person("张三",18));s2.add(new Person("李四",19));s2.add(new Person("王五",20));s2.add(new Person("赵六",19));s2.add(new Person("刘八",20));for (Object o : s2) {System.out.println(o);}
输出结果为:
重写的hashCode和equals方法以及重写后的输出结果:
@Overridepublic int hashCode() {//重写hashCodeint hash = Objects.hash(name,age);//根据属性值产生hash值System.out.println(hash);return hash;}@Overridepublic boolean equals(Object obj) {//重写equals if (this.age==age && this.name==name){//这里的this是指调用此方法的对象,避免了存入对象的重复。return true;}return super.equals(obj);}
结果中上半的数字为自定义对象的哈希值,下半为集合遍历结果。
最后附上Person类完整代码
import java.util.Objects;public class Person {private String name;private int age;public void show(){System.out.println("姓名:"+name+"\n"+"年龄:"+age);}public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic int hashCode() {//重写hashCodeint hash = Objects.hash(name,age);//根据属性值产生hash值System.out.println(hash);return hash;}@Overridepublic boolean equals(Object obj) {//重写equalsif (this.age==age && this.name==name){//这里的this是指调用此方法的对象,避免了存入对象的重复。return true;}return super.equals(obj);}
}
Map
双列集合顶层接口,描述的是一个数据(Key)到另一个数据(Value)的映射关系。
Map<K,V>的特点:
每一对称为键值对,描述的是映射关系
key是唯一的,value是不唯一的
每个键都能确定一个与之对应的值
Map集合中没有索引,所以存储的元素不能保证顺序
HashMap
HashMap<K,V>存储数据采用哈希表结构,元素存储的顺序和取出的顺序不能保证一致,由于键是唯一的,所以存储自定义元素的时候,也要重写hashCode和equals
常用的方法:
put(K key,V value):如果添加的key在Map集合中不存在,那么put方法将键值对添加到Map集合中,返回值为null;如果添加的key在Map集合中存在,那么put方法将修改key对应的value值,返回值就是修改之前的value
remove(Object key):把指定的键所对应的键值对,从Map集合中删除,返回被删除元素的值
get(Object key):根据指定的键,在Map中获取对应的值
boolean containsKey(Object key):判断集合中是否包含指定的键
boolean containsValue(Object value):判断集合是否包含指定的值
clear():清空集合
isEmpty():判断是否为空
size():获取集合中键值对的个数
Map集合遍历
1、通过键遍历
获取Map集合的所有键: Set keySet();
通过迭代器或增强for循环遍历
2、键值对遍历
获取Map集合中的所有键值对对象(Entry),使用Map集合的entrySet(),返回值是一个Set集合,可以获取所有的键值对对象
遍历包含键值对对象的Set集合,得到每一个键值对(Entry对象)
通过键值对对象提供的getKey()和getValue()方法获取该键值对的键与值
//map双列集合HashMap<String,String> m = new HashMap();//添加元素m.put("张三","员工");m.put("王五","员工");m.put("李四","部长");m.put("赵六","部长");m.put("陈七","老板");System.out.println(m);//遍历Set k = m.keySet();//将key值存储到set集合中//增强for循环System.out.println("增强for循环遍历:");for (Object o : k) {System.out.print(m.get(o)+"\t");//通过key值遍历出对应的value值}//迭代器遍历System.out.println();System.out.println("迭代器遍历:");Iterator iterator = k.iterator();while (iterator.hasNext()){Object next = iterator.next();System.out.print(m.get(next)+"\t");}System.out.println();//键值对遍历Set<Map.Entry<String, String>> s = m.entrySet();//将键值对对象存入set集合中,entrySet()可获取所有键值对对象for (Map.Entry<String, String> e : s) {String key = e.getKey();//通过getKey()获取key值String value = e.getValue();//通过getValue()获取value值System.out.println(key+": "+value);}
附上运行结果:
数据结构
数据结构是计算机存储、组织数据的方式,通常情况下,精心选择的数据结构可以带来更高的运行和存储的效率。
栈
1、栈:stack,又称为堆栈,它是运算受限的线性表,其限制是仅允许在标的一端插入和删除操作,不允许在其他任何位置进行添加、查找、删除等操作。
2、特点:先进后出
压栈:就是存元素的过程,即把元素存储到栈的顶端位置,栈中已有元素一次向栈底移动一格
弹栈:就是取元素的过程,即把栈的顶端位置元素取出,栈中已有元素依次向栈顶的方向移动一格
队列
1、queue,简称队,同堆栈一样,也是运算受限的线性表,其限制是仅允许在表的一端进行插入,在表的另一端进行删除
2、特点:先进先出
数组
Array:是有序的元素序列,数组在内存中,开辟一块连续的空间,并在此空间中存放元素
特点:查改元素快,可以根据编号找到对应的房间
增删元素慢
链表
1、由一系列节点node(链表中的每一个元素被称为节点)组成,节点存储是一个动态生成,每个节点包含两部分:一个是存储元素的数据域,另一个是存储下一个节点地址的指针域,我们常说的链表结构,有单向链表和双向链表
2、采用链表结构存储的元素,对元素存取有以下特点:
多个节点之间使用地址链接
查找元素慢,想要查找某个元素,需要通过连接的节点,指针域,找到下一个元素,依次进行排查
增删元素快,只需要修改指针域的指向
ArrayList
1、ArrayList是List的实现类
当创建ArrayList集合的时候,会维护一个长度为10的Object类型的数组
当插入数据10个长度不够的时候,此时会以1.5倍的形式进行扩容
存储特点:增删慢,查改快
2、实际开发中,ArrayList用的最多,很多功能都需要用到统计查询
3、ArrayList查改快,数组的第一个元素被称为首地址,根据首地址+索引偏移量就可以直接算出目标元素的位置,从而快速定位
4、增删慢:想要中间添加元素,相对比较慢,添加位置以后的所有元素,都要向后移动一位,集合规模越大,所需要的时间越多
LinkedList
1、集合存储的元素是双向链表,方便元素添加和删除
2、该类型有大量的对于头部和尾部操作的方法
3、特点:查询慢,增删快,链表结构不需要连续的空间,可以利用内存中零散的空间进行存储
4、常用方法:
addFirst(Object o):向头部添加元素
addLast(Object o):向尾部添加元素
getFirst():获取头部元素
getLast():获取尾部元素
removeFirst():删除头部元素(返回被删除的元素,可以不接收)
removeLast():删除尾部元素(返回被删除的元素,可以不接收)
LinkedList l = new LinkedList();l.add(1);l.add(2);l.add(3);l.add(4);l.add(5);System.out.println("LinkedList集合:");for (Object o : l) {System.out.print(o+"\t");}//增加头部、尾部System.out.println();l.addFirst(0);l.addLast(9);for (Object o : l) {System.out.print(o+"\t");}//获取并删除头尾System.out.println();Object first = l.getFirst();Object last = l.getLast();l.removeFirst();l.removeLast();for (Object o : l) {System.out.print(o+"\t");}System.out.println("\n"+"头:"+first+"\n"+"尾:"+last);
Collections工具类
1、Collections是一个单列集合的工具类,在类中封装了很多常用的操作集合的方法,因为该类没有提供构造方法,因此不能创建对象,类中的方法都是静态方法,通过类名调用
2、常用方法:
sort(List list):将列表按照升序排列,从小到大(只能是Integer类型的数据,比如Set集合中获得的键值存储在链表中)
max、min(Collection c):获取集合中的最大值、最小值
replaceAll(LIstlist,E oldValue,E newValue):将list集合中的老元素替换为新元素
reverse(List list):将参数list集合进行反转
shuffle(List list):将list集合中的元素进行随机置换
更多推荐
Java基础(二)集合
发布评论