3.3 实例
3.3.1 新增元素
package com.caq.oop.demo08; import java.util.ArrayList; public class Test { public static void main(String[] args) { //实例化一个空列表 ArrayList arrayList = new ArrayList(); for (int i = 0; i < 5; i++) { //将元素i追加到列表的末尾 arrayList.add(i); //打印列表 System.out.println(arrayList); } } }
运行结果:
[0] [0, 1] [0, 1, 2] [0, 1, 2, 3] [0, 1, 2, 3, 4]
代码中,首先实例化了一个ArrayList对象,然后使用 for 循环语句循环 5 次,每次都向arrayList对象中追加变量i,并打印列表内容,运行结果清晰的展示了每次新增元素的过程。
Tips:由于ArrayList的父类AbstractCollection重写了toString()方法,因此直接打印列表,可以直观地展示出列表中的元素。
3.3.2 泛型初识
Tips:泛型(Genericity)
介绍一下泛型以及其使用方法。
如果你使用IDEA编写如上代码,将会有下图所示的 3 处黄色警告:
既然IDE有了警告,我们就尝试来解决一下,将鼠标光标放置到警告处,会提示“Unchecked call to ‘add(E)’ as a member of raw type ‘java.util.List’ ”,这是IDE的泛型检查,可点击Try to generify 'ArrayListDemo1.java'按钮:
此时会出现一个Generify的弹窗,直接点击Refactor按钮:
代码变成了下图所示的样子,那 3 处警告被成功消除了:
List类型后面多了一对尖括号“<>”,<>里面是 Java 的包装类型Integer,在ArrayList类型后面也多了一对尖括号,这里的<>中承载的就是 Java 的泛型的类型参数,它表示arrayList对象用于存放Integer类型的数据。
我们只需知道这样做就可以消除IDEA的警告即可。后面会继续深入!
由于前面List已经指定了泛型的参数类型为Integer,后面的ArrayList就不需要再重复指定了。当然你也可以这样写(但是没必要):
List<Integer> arrayList = new ArrayList<Integer>();
同理,如果你想向arrayList存放String类型的元素,只需将<Integer>改为<String>,我们再来看一个实例:
实例演示
package com.caq.oop.demo08; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { //实例化一个空列表 List<String> arrayList = new ArrayList<>(); //将Hello打印到arrayList列表的末尾 arrayList.add("Hello"); arrayList.add("Hello"); //打印列表 System.out.println(arrayList); //将字符串元素Monkey插入到此列表中的索引为1的位置 arrayList.add(1, "Monkey"); } }
两种形式,直接最后添加字符换或者指定索引添加,IDEA这点做的还是挺好的!!!
[Hello, Hello] [Hello, Monkey, Hello]
代码中,首先实例化了一个ArrayList的对象,调用了两次add(E e)方法,依次向列表尾部插入了Hello和World元素,列表中元素为[Hello, World],此时调用add(int index, E element)方法,将字符串元素 Java 插入到此列表中的索引为 1 的位置,因此列表中的元素为[Hello, Java, World]。
3.3.3 删除元素
实例演示
package com.caq.oop.demo08; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { //实例化一个空列表 List<String> arrayList = new ArrayList<>(); //将Hello打印到arrayList列表的末尾 arrayList.add("Hello"); arrayList.add("Hello"); arrayList.add("Hello"); arrayList.add("Tiger"); //打印列表 System.out.println(arrayList); //删除索引为3的元素 arrayList.remove(3); //打印列表 System.out.println(arrayList); //删除列表第一次出现的Hello元素 arrayList.remove("Hello"); System.out.println(arrayList); } }
运行结果:
[Hello, Hello, Hello, Tiger] [Hello, Hello, Hello] [Hello, Hello]
代码中,我们首先添加了 4 个字符串元素,列表内容为[Hello, World, Hello, Java],然后调用remove(int index)方法删除了索引位置为 3 的元素(即Java),此时列表内容为[Hello, World, Hello] ,再次调用remove(Object o)方法,删除了列表中第一次出现的Hello元素,此时列表内容为[World, Hello]。
3.3.4 修改元素
可使用set()方法修改列表中元素,实例如下:
实例演示
package com.caq.oop.demo08; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { //实例化一个空列表 List<String> arrayList = new ArrayList<>(); arrayList.add("Hello!"); arrayList.add("Hello!"); //打印 System.out.println(arrayList); //用字符串元素Hello替换列表索引位置为1的元素 arrayList.set(1,"Monkey"); System.out.println(arrayList); } }
运行结果:
[Hello!, Hello!] [Hello!, Monkey]
3.3.5 查询元素
可使用get()方法来获取列表中元素,实例如下:
实例演示
package com.caq.oop.demo08; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { //实例化一个空列表 List<String> arrayList = new ArrayList<>(); arrayList.add("Hello0"); arrayList.add("Hello1"); //用get方法查询索引为1的元素 for (int i = 0; i < arrayList.size(); i++) { System.out.println("索引为" + i + "元素为:" + arrayList.get(i)); } } }
运行结果:
索引为0元素为:Hello0 索引为1元素为:Hello1
我们在使用for循环遍历列表的时候,让限定条件为i < arrayList.size();,size()方法可获取该列表中元素的数量。
请查看如下实例:
实例演示
package com.caq.oop.demo08; /* 当我们打印一个对象的引用时,实际是默认调用这个对象的toString()方法 当打印的对象所在类没有重写Object中的toString()方法时,默认调用的是Object类中toString()方法。 返回此对象所在的类及对应的堆空间对象实体的首地址值 当我们打印对象所在类重写了toString(),调用的就是已经重写了的toString()方法,一般重写是将类对象的属性信息返回。 toString 方法会在 println 的时候被自动调用. 将对象转成字符串这样的操作我们称为 序列化. toString 是 Object 类提供的方法, 我们自己创建的 Person 类默认继承自 Object 类, 可以重写 toString 方法实 现我们自己版本的转换字符串方法 */ //自定义类需要重写toString方法,通过字符串的方式显示对象 import java.util.ArrayList; import java.util.List; public class Test { static class NBA { private String name; private String position; public NBA(String name, String position) { this.name = name; this.position = position; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPosition() { return position; } public void setPosition(String position) { this.position = position; } @Override public String toString() { return "NBA{" + "name='" + name + '\'' + ", position='" + position + '\'' + '}'; } public static void main(String[] args) { //实例化一个空列表 List<NBA> arrayList = new ArrayList<>(); //实例化3个NBA对象 NBA nba1 = new NBA("乔丹","得分后卫SG"); NBA nba2 = new NBA("詹姆斯","小前锋SF"); NBA nba3 = new NBA("库里","控球后卫PG"); //新增元素 arrayList.add(nba1); arrayList.add(nba2); arrayList.add(nba3); System.out.println(arrayList); //删除元素 arrayList.remove(nba3); System.out.println("删除后的动态数组arraylist为:"+arrayList); arrayList.remove(1); System.out.println("删除后的动态数组索引为1的元素arraylist为:"+arrayList); //修改元素 NBA nba4 = new NBA("格里芬","大前锋PF"); arrayList.set(0,nba4); //查询元素,将get()方法得到的object类强制转化为NBA类型 NBA player = arrayList.get(0); System.out.println("索引为0的球员昵称为:"+player.getName()); System.out.println("索引为0的球员位置为:"+player.getPosition()); } } }
运行结果:
[NBA{name='乔丹', position='得分后卫SG'}, NBA{name='詹姆斯', position='小前锋SF'}, NBA{name='库里', position='控球后卫PG'}] 删除后的动态数组arraylist为:[NBA{name='乔丹', position='得分后卫SG'}, NBA{name='詹姆斯', position='小前锋SF'}] 删除后的动态数组索引为1的元素arraylist为:[NBA{name='乔丹', position='得分后卫SG'}] 索引为0的球员昵称为:格里芬 索引为0的球员位置为:大前锋PF
为了方便演示,我们定义了一个静态内部类NBA,它有两个属性name和position,定义了属性的getter和setter,并重写了toString()方法。在main()方法中,我们实现了自定义类在ArrayList中的增删改查。
3.4 LinkedList 实现类
LinkedList 是一个以双向链表实现的List。和ArrayList一样,也按照索引位置排序,但它的元素是双向连接的,因此顺序访问的效率非常高,而随机访问的效率比较低。
3.4.1 构造方法
LinkedList():构造一个空列表;
LinkedList(Collection<? extends E> c):构造一个包含指定集合元素的列表,其顺序由集合的迭代器返回。
3.4.2 常用成员方法
void add(E e):将指定的元素追加到此列表的末尾;
void add(int index, E element):将指定的元素插入此列表中的指定位置;
void addFirst(E e):将指定的元素插入此列表的开头;
vod addLast(E e):将指定的元素添加到此列表的结尾;
E remove(int index):删除此列表中指定位置的元素;
boolean remove(Object o):如果存在指定元素,则从该列表中删除第一次出现的该元素;
void clear():从此列表中删除所有元素;
E set(int index, E element):用指定的元素替换此列表中指定位置的元素;
E get(int index):返回此列表中指定位置的元素;
E getFirst():返回此列表的第一个元素;
E getLast():返回此列表的最后一个元素;
boolean contains(Object o):如果此列表包含指定的元素,则返回 true,否则返回 false;
int size():返回该列表中元素的数量;
Object[] toArray():以正确的顺序(从第一个元素到最后一个元素)返回一个包含此列表中所有元素的数组。
4. Set 集合
4.1 概念和特性
Set是元素无序并且不可以重复的集合,我们称之为集(有序可以重复成为序列)。Set是Collection的一个子接口,它的主要实现类有:HashSet、TreeSet、LinkedHashSet、EnumSet等,下面我们将详细介绍最常用的HashSet实现类。
4.2 HashSet 实现类
HashSet类依赖于哈希表(实际上是HashMap实例,下面将会介绍)。HashSet中的元素是无序的、散列的。
4.2.1 构造方法
HashSet():构造一个新的空集;默认的初始容量为 16(最常用),负载系数为 0.75;
HashSet(int initialCapacity):构造一个新的空集; 具有指定的初始容量,负载系数为 0.75;
HashSet(int initialCapacity, float loadFactor):构造一个新的空集; 支持的 HashMap 实例具有指定的初始容量和指定的负载系数;
HashSet(Collection<? extends E> c):构造一个新集合,其中包含指定集合中的元素。
4.2.2 常用成员方法
HashSet的常用成员方法如下:
boolean add(E e):如果指定的元素尚不存在,则将其添加到该集合中;
boolean contains(Object o):如果此集合包含指定的元素,则返回 true,否则返回 false;
boolean isEmpty():如果此集合不包含任何元素,则返回 true,否则返回 false;
Iterator<E> iterator():返回此集合中元素的迭代器;
boolean remove(Object o):从该集合中删除指定的元素(如果存在);
int size():返回此集合中的元素数量。
4.3 实例
4.3.1 新增元素
实例演示
package com.caq.oop.demo08; import java.util.Set; import java.util.HashSet; public class Test { public static void main(String[] args) { //实例化一个新的空集 Set<String> hashSet = new HashSet<>(); //向hashSet集中依次添加元素 hashSet.add("Monkey"); hashSet.add("Monkey"); hashSet.add("Tiger"); hashSet.add("Dog"); hashSet.add("Cat"); // 打印 hashSet 的内容 System.out.println("hashSet中的内容为:" + hashSet); } }
运行结果:
hashSet中的内容为:[Monkey, Cat, Dog, Tiger]
在实例中,我们先后向hashSet中添加了两次Monkey元素,由于集的元素不可重复特性,因此集中只允许出现一个Monkey元素。我们还观察到,打印结果的元素顺序和我们添加的顺序是不同的,这验证了集的无序特性。
Tips: 由于HashSet的父类AbstractCollection重写了toString()方法,因此直接打印集,可以直观地展示出集中的元素。
4.3.2 删除元素
可使用remove()方法删除集中元素
实例演示
package com.caq.oop.demo08; import java.util.ArrayList; import java.util.Set; import java.util.HashSet; public class Test { public static void main(String[] args) { //实例化一个新的空集 Set<String> hashSet = new HashSet<>(); //向hashSet集中依次添加元素 hashSet.add("Monkey"); hashSet.add("Monkey"); hashSet.add("Tiger"); hashSet.add("Dog"); hashSet.add("Cat"); System.out.println("hashSet中的内容为:" + hashSet); hashSet.remove("Cat"); System.out.println("hashSet中的内容为:" + hashSet); } }
运行结果:
hashSet中的内容为:[Monkey, Cat, Dog, Tiger] hashSet中的内容为:[Monkey, Dog, Tiger]