强哥说Java--Java集合(二)

简介: 强哥说Java--Java集合(二)

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]



相关文章
|
18天前
|
安全 Java 大数据
|
16天前
|
安全 Java 开发者
【JAVA】哪些集合类是线程安全的
【JAVA】哪些集合类是线程安全的
|
16天前
|
Java
【JAVA】怎么确保一个集合不能被修改
【JAVA】怎么确保一个集合不能被修改
|
2天前
|
存储 安全 Java
Java一分钟之-集合框架进阶:Set接口与HashSet
【5月更文挑战第10天】本文介绍了Java集合框架中的`Set`接口和`HashSet`类。`Set`接口继承自`Collection`,特征是不允许重复元素,顺序不确定。`HashSet`是`Set`的实现,基于哈希表,提供快速添加、删除和查找操作,但无序且非线程安全。文章讨论了`HashSet`的特性、常见问题(如元素比较规则、非唯一性和线程安全性)以及如何避免这些问题,并提供了代码示例展示基本操作和自定义对象的使用。理解这些概念和注意事项能提升代码效率和可维护性。
9 0
|
2天前
|
存储 安全 算法
Java一分钟之-Java集合框架入门:List接口与ArrayList
【5月更文挑战第10天】本文介绍了Java集合框架中的`List`接口和`ArrayList`实现类。`List`是有序集合,支持元素重复并能按索引访问。核心方法包括添加、删除、获取和设置元素。`ArrayList`基于动态数组,提供高效随机访问和自动扩容,但非线程安全。文章讨论了三个常见问题:索引越界、遍历时修改集合和并发修改,并给出避免策略。通过示例代码展示了基本操作和安全遍历删除。理解并正确使用`List`和`ArrayList`能提升程序效率和稳定性。
7 0
|
4天前
|
存储 安全 算法
掌握Java并发编程:Lock、Condition与并发集合
掌握Java并发编程:Lock、Condition与并发集合
11 0
|
4天前
|
存储 安全 Java
深入理解Java集合框架
深入理解Java集合框架
10 0
|
10天前
|
存储 安全 Java
Java集合的分类有哪些?
Java中的集合就像一个容器,专门用来存储Java对象,这些对象可以是任意的数据类型,并且长度可变。这些集合类都位于java.util包中,在使用时一定要注意导包的问题,否则会出现异常。
36 10
|
13天前
|
安全 Java
循环的时候去删除集合中的元素 java.util.ConcurrentModificationException
循环的时候去删除集合中的元素 java.util.ConcurrentModificationException
|
14天前
|
Java
【专栏】Java 8 的 Streams 提供了一种处理数据集合的新方式,增强了代码的可读性和可维护性
【4月更文挑战第28天】Java 8 的 Streams 提供了一种处理数据集合的新方式,增强了代码的可读性和可维护性。本文介绍了 Streams 的基本概念,如从数据源创建 Stream,以及中间和终端操作。通过过滤、映射、归并、排序、分组等案例,展示了 Streams 的使用,包括并行 Streams 提高效率。学习 Streams 可以提升代码质量和效率,文章鼓励读者在实际开发中探索更多 Streams 功能。