Java集合

集合:工具类,可以存储任意数量具有共同属性的对象的容器

使用集合而不使用数组的场景
1、无法预测存储数据的数量
2、同时存储一对一关系数据
3、需要进行数据的增删(动态增长)
4、数据重复问题

集合框架的体系结构

在这里插入图片描述
1、集合分为Collection和Map两类,Collection存储类的对象,Map存储键值对信息
2、Collection接口下有三个子接口,List与Queue中存储有序且允许重复的对象,Set中存储无序且不允许重复的对象,List的实现类包括ArrayList,ArrayList可看作长度动态变化的数组

List(列表)

1、元素有序可重复的集合
2、可精确地控制某个位置的元素(删除、插入方便)。。应该是因为有序吧
3、两个实现类:ArrayList LinkedList
4、ArrayList底层是由数组实现,与数组类似,也是在内存中的一片连续空间存储,因此在ArrayList列表尾部插入或删除数据非常有效,在中间插入需要进行大量数组复制,因此不适合
5、ArrayList元素可为null值。。。应该是因为存储对象,对象默认值为null吧
6、ArrayList更适合查找更新元素(类似数组)

常用方法

Collection:****add() clear() contains() isEmpty() remove() toArray() size()(集合转换成数组)
**List:**get(int index) **indexof()(两个不要搞混,类似的有String里的 charAt()和indexOf()) sort() **
ArrayList:构造函数:
ArrayList();
ArrayList(已存在的集合数据);
ArrayList(初始化容量);
ArrayList重写了toString方法:System.out.println(列表名)输出所有内容

在ArrayList中添加字符串对象

 ArrayList arrayList=new ArrayList();
        //List l=new ArrayList();接口引用指向实现类
        arrayList.add("Java");
        arrayList.add("C++");
        arrayList.add("C");
        String[] s=new String[3];
        s[0]="Java";
        s[1]="C++";
        //输出列表中元素的个数
        System.out.println(arrayList.size());
        //遍历输出所有内容
        System.out.println(arrayList);
        //遍历输出所有内容
        for(int i=0;i<arrayList.size();i++)
            System.out.println(arrayList.get(i));

        //移除列表中的C++
       // arrayList.remove("C++");
        arrayList.remove(1);
        System.out.println(arrayList);
        System.out.println(s);
        for(String i:s)
        System.out.println(i);

在ArrayList中添加自定义类的对象(增删改查)(add remove size get set)

添加公告,显示公告,在指定位置添加公告删除公告,修改公告
添加公告:add方法,在末尾添加
显示公告:get方法的返回值是一个Object对象,需要对返回值进行强制转换,把父类Object的对象强制转换成子类的对象,再调用类内的get方法,遍历显示内容(之前想的改写toString方法有问题,因为返回的是Object对象,改写了类的toString方法也不会有效,不对,重写父类的方法是会被直接调用的,独有的方法则需要强制转换再调用)
在这里插入图片描述

在指定位置添加公告:add方法,在列表中间添加
删除公告:remove方法
修改公告:创建了新的对象去替换旧的对象需要调用ArrayList的set方法

public class ListDemo2 {
    public static void main(String[] args) {
        ArrayList arrayList=new ArrayList();
        Brief notice1=new Brief("公告一",1);
        Brief notice2=new Brief("公告二",2);
        Brief notice3=new Brief("公告三",3);
        //添加公告,add在末尾添加
        arrayList.add(notice1);
        arrayList.add(notice2);
        arrayList.add(notice3);
//        System.out.println(arrayList.get(0));//方法获取的是对象,因此需要重写toString方法
//        System.out.println(arrayList);
        //显示公告
        for(int i=0;i<arrayList.size();i++){
            System.out.println(i+":"+((Brief)(arrayList.get(i))).getTime());
            //+可进行字符串连接和加法运算,可同时进行
        }
        //在指定位置添加公告删除公告,以及公告的修改
        //在第一条公告后面添加一条新公告,add在中间指定位置插入
        arrayList.add(1,new Brief("公告四",4));
        //删除公告
        //arrayList.remove(0);
        arrayList.remove(notice1);
        for(int i=0;i<arrayList.size();i++){
            System.out.println(i+":"+((Brief)(arrayList.get(i))).getTime());
            //+可进行字符串连接和加法运算,可同时进行
        }
        //修改公告
        //先修改对象中的内容,再修改ArrayList
        notice3.setContents("修改了");
        //set把arraylist中对象的值重新设置一遍(如果创建了新的对象去替换旧的对象需要调用ArrayList的set方法
        arrayList.set(2,notice3);
        for(int i=0;i<arrayList.size();i++){
            System.out.println(i+":"+((Brief)(arrayList.get(i))).getContents());
            //+可进行字符串连接和加法运算,可同时进行
        }
    }
}


class Brief{
    private String contents;
    private int time;


    public int getTime() {
        return time;
    }

    public void setTime(int time) {
        this.time = time;
    }


    public String getContents() {
        return contents;
    }

    public void setContents(String contents) {
        this.contents = contents;
    }

    public Brief(String contents,int time) {
        this.contents = contents;
        this.time=time;
    }

    @Override
    public String toString() {
        return this.contents+this.time;
    }
}

Set:元素不可重复的集合,称为集

1、HashSet中元素无序且不可重复
2、实现类HashSet只允许包含一个null元素(因为不允许重复)
3、HashSet具有良好的存取和查找性能
4、HashSet底层是HashMap
5、HashSet的构造方法:HashSet() HashSet(已存在的集合数据) HashSet(初始容量)

Set方法:add、addAll、clear、contains、equals、hashcode、iterator、size、remove、toArray

在Set中添加字符串对象

1、向集合中添加元素

 HashSet a=new HashSet(5);
        //向集合中添加元素
        a.add("blue");
        a.add("red");
        a.add("black");
        a.add("yellow");
        a.add("white");

2、显示集合中的元素(遍历),没有get方法,使用迭代器接口
(1)Iterator接口可以以统一的方式**对各种集合元素(ArrayList也可以用)**进行遍历
(2)Iterator接口中的hasNext()方法检测集合中是否还有下一个元素
(3)Iterator接口中的next()方法返回集合中的下一个元素
可能是新的接口使用方法吧,跟前面的不太一样,接口本质上还是一个类

Iterator it=a.iterator();

集合调用iterator()方法把结果存放到Iterator的引用中(Set不能使用get方法取出元素,那么把集合中的数据放到迭代器中,使用迭代器的方法取出集合的元素)
遍历迭代器输出元素

 while(it.hasNext()){
            System.out.print(it.next()+" ");
        }

3、在集合中插入新的单词,Set与ArrayList相比是无序的,因此只有一种在末尾添加元素的add方法,不能使用索引在中间指定位置添加
插入重复元素后遍历迭代器并输出,插入失败,但是不会报错,系统不会插入重复元素

        a.add("black");
        //插入重复元素后遍历迭代器并输出,插入失败,但是不会报错,系统不会插入重复元素
        it=a.iterator();
        while(it.hasNext()){
            System.out.print(it.next()+" ");
        }

在HashSet中加入自定义类的对象

1、添加和显示宠物猫信息
while(i.hasNext())返回集合元素对象的引用,输出时自动调用类的toString方法,输出的是地址信息
stringdemo.Cat@2f4d3709 stringdemo.Cat@b4c966a stringdemo.Cat@4e50df2e
因此需要重写toString方法

public class SetDemo2 {
    public static void main(String[] args) {
        Cat cat1=new Cat("猫1","品种1",2);
        Cat cat2=new Cat("猫2","品种2",4);
        Cat cat3=new Cat("猫3","品种3",6);
        HashSet set=new HashSet();
        set.add(cat1);
        set.add(cat2);
        set.add(cat3);
        Iterator i= set.iterator();
        while(i.hasNext())
            //返回集合元素对象的引用,输出时自动调用类的toString方法,输出的是地址信息
            //stringdemo.Cat@2f4d3709 stringdemo.Cat@b4c966a stringdemo.Cat@4e50df2e
            //重写toString方法
            System.out.print(i.next()+" ");

    }
}


class Cat{
    private String name;
    private String species;
    private int month;

    public String getSpecies() {
        return species;
    }

    public void setSpecies(String species) {
        this.species = species;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public Cat(String name, String species,int month) {
        this.month = month;
        this.name=name;
        this.species=species;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", species='" + species + '\'' +
                ", month=" + month +
                '}';
    }
}

2、添加重复的宠物猫信息

Cat cat4=new Cat("猫3","品种3",6);
set.add(cat4);
//重新取一下集合中的元素放到迭代器中
//在类中重写Object中hashCode和equals方法
i=set.iterator();//重新取集合中的元素放到迭代器中
while(i.hasNext())
    System.out.println(i.next()+" ");

i=set.iterator();//重新取集合中的元素放到迭代器中
输出了重复元素,与元素是字符串时不同,字符串是系统给的类,判断数据是否重复的规则已经定义好了(String类重写了hashCode和equals方法,可以直接使用,而自己定义的类则需要修改判断是否重复的方法,所以需要在类中重写Object中hashCode和equals方法

hashCode()方法

需了解数据结构哈希表(hashtable)(存储方式),可提高数据的查找速度
在这里插入图片描述
假设存储了100个数据,需要查找第100个数据,若使用ArrayList或数组在一片连续空间存储数据,则需要从第一个数据挨个循环比较数据遍历到第100个数据,当数据量大的情况下效率低下使用哈希表存取,假设在内存中开辟三个区域存放正整数,如定义hashCode=n%3,hashCode规定这100个数据里什么数据放在哪个桶里,在查找时先判断要查找的数据会在哪个区域里(使用hashCode进行比较),找到所在区域再遍历元素(使用equals方法)

所以为了提高查询速度,需要重写hashCode和equals方法

在这里插入图片描述
1、hashCode相同不一定是同一个对象,需要进一步使用equals判断


public boolean equals(Object o) {//两个对象进行比较
       //this当前对象和o传进来的对象相等,相等则返回true,不用再继续比较内容
       if(this==o)
            return true;
       //反射,判断o是否是Cat类的对象,如果是则强制转换,返回两个对象属性比较之后的结果
        if(o.getClass()==Cat.class) {
            Cat cat = (Cat) o;//强制转换
            //cat的属性和当前对象的属性
           return cat.getName().equals(name) && cat.getMonth()==month&&cat.getSpecies().equals(species);
            //判断两个Cat对象属性是否相等
       }
       //以上都不满足,不相等
       return false;
    }

2、查找某只宠物猫的信息并输出
方式一:使用对象名查找

if (set.contains(cat1)) {
    System.out.println("找到cat1");
    System.out.println(cat1);
}

方式二:通过名字进行查找,遍历集合

i = set.iterator();//进行一次操作就要重新取集合中的元素放到迭代器中,是next从头开始遍历
boolean flag = false;
Cat c = null;//为了保存住遍历到的对象,定义在循环内部
while (i.hasNext()) {
    c = (Cat) (i.next());//next()得到object类的对象,需要强制转换
    if (c.getName().equals("cat1")) {
        flag = true;//flag查询
        break;
    }
}
    if (flag) {
        System.out.println("找到cat1");
        System.out.println(c);
    }

引入泛型:在类或接口添加<元素类型>,泛型规定了插入集合的元素必须是某一类型,与c = (Cat) (i.next());//next()得到object类的对象,需要强制转换 相比 c=i.next();无需添加显示强制类型转换,可直接被隐式类型转换

Set<Cat> set=new HashSet<Cat>;
HashSet<Cat> set=new HashSet<Cat>;

Iterator<Cat> it=set.iterator();

set中删除元素for-each避免异常的方法

4、删除某宠物猫信息并显示,引入泛型后可使用for增强循环进行遍历(或使用迭代器)(因为集合中的元素类型已经被指定)

for(Cat n:set)
 if(n.getName().equals("cat1");
   set.remove(n);

for(Cat n:set)
   System.out.println(n);

迭代器遍历后删除不会报错
 while(!i.hasNext()) {
            if (i.next().getContents().equals("公告一"))
                l.remove(i);
        }

在这里插入图片描述
进行上面的操作会报错: **

set的size是动态变化的,当移除一个元素后,长度变化了,不会按照原来的规则进行遍历(set是无序的),因此报错,完成所需操作时就应该退出遍历,(注意for-each循环,可能for-size的遍历可以时刻更新size的变化,iterator hasNext的遍历也可以时刻更新size的变化)修改如下:

**

for(Cat n:set)
 if(n.getName().equals("cat1");{
   set.remove(n);
   break;}




在ArrayList中进行删除操作时类似,for增强循环会报错,普通遍历不报错
  for(Brief n:l)
            if(n.getContents().equals("公告一"))
                l.remove(n);
        for(int i=0;i<l.size();i++)
            if(l.get(i).getContents().equals("公告一"))
                l.remove(i);

在ArrayList中进行删除操作时类似,for增强循环会报错,普通遍历不报错

5、删除多个宠物猫信息,removeAll()括号中的参数可以是一个集合(可以是集合的子集)
(1)创建一个新的集合

Set set1=new HashSet();

(2)将符合条件的元素添加到新的集合中

for(Cat n:set)
  if(n.getMonth<3)
  set1.add(n);
set.removeAll(set1);

6、删除所有宠物猫信息

set.removeAll();
if(set.isEmpty())

Map:重要的三个方法,获取键值对对象所在集合entrySet()、获取键所在集合keySet()、获取值所在集合values(),添加键值对put(k,v),获取键对应的值get();注意泛型,HashMap创建是用的是<String,String>,获取键值对对象所在集合时用的是<Map.Entry<String,String>>(所以对hashmap的操作与对hashset的操作相比多了一步entrySet),获取键和值所在集合时用的是;entrySet()k-v组合到一起就是一个entry的对象,把hashmap里的键值对全部放到一个entry的集合中,就可以遍历集合

在这里插入图片描述

(1)Entry是Map中的一个接口,k-v以键值对的形式存储到接口对象中
(2)HashSet是在HashMap基础上实现的
(3)HashMap中只能有一个null键
(4)Entry对象就是k-v键值对所对应的实例k-v是一种形式,实际上是Entry实例),Entry对象无序排列
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Map中的方法

获取Entry键值对的所有内容,返回一个Set,限定了返回元素是Map.Entry<K,V>
在这里插入图片描述

获取key对应的value值
在这里插入图片描述

与entrySet对应,取出所有K值,返回一个Set
在这里插入图片描述

与HashSet中添加新元素的add方法不同,HashMap中添加新元素使用put方法
在这里插入图片描述

根据key值移除map中的元素
在这里插入图片描述

返回一个集合的对象,集合中元素是value值
在这里插入图片描述
key和value也是对象

HashMap的方法

HashMap中的构造方法与HashSet类似
在这里插入图片描述

**

  • 完成一个类似字典的功能
  • 1、将单词以及单词的注释存储到HashMap中
  • 2、显示HashMap中的内容
  • 3、查找某个单词的注释并显示

*/

public class MapDemo1 {
    public static void main(String[] args) {

        HashMap<String,String> hp=new HashMap<String,String>();
        //从键盘输入单词和对应的注释
        System.out.println("请输入三组单词对应的注释,并存放到HashMap中");
        Scanner sc=new Scanner(System.in);
        //添加数据
        int i=0;
        while(i<3){
            System.out.println("请输入key值");
            String key=sc.next();
            System.out.println("请输入value值");
            String value=sc.next();
            hp.put(key,value);
            i++;
        }
      //打印输出value的值(直接使用迭代器)
        System.out.println("使用迭代器输出所有value");
        Iterator<String> it=hp.values().iterator();//values返回集合后调用集合的iterator方法,存储到迭代器中
        while(it.hasNext())
            System.out.println(it.next());

        //打印输出key和value的值(通过entrySet方法得到k-v)
        Set<Map.Entry<String,String>> set=hp.entrySet();//k-v组合到一起就是一个entry的对象,把hashmap里的键值对全部放到一个entry的集合中,就可以遍历集合
                     //把内容都取出来,Set后加泛型,Entry后也要加泛型,注意辨别
        //使用增强型for循环遍历集合
        for(Map.Entry<String,String> n:set){
            System.out.println(n.getKey());
            System.out.println(n.getValue());
        }




 //通过单词找到注释并输出,
 使用keySet方法直接获取key或
 使用entrySet和getKey联合先获取entry对象再获取key
        //使用keySet方法
        //取得keySet
        Set<String> set1=map.keySet();
        //遍历keySet
        for(String i:set1)
            if(i.equals("单词一")){
            System.out.println(map.get(i));
            break;}

    }

与前面的简单添加元素不一样,使用了键盘输入,因此就需要对输入参数的合法性进行判断,引入重复数据判断(containsKey())和异常处理(try-catch)

商品信息管理
商品信息添加

public class MapDemo3 {
    public static void main(String[] args) {
        //引入重复数据判断和异常处理
        HashMap<String,Product> map=new HashMap<String, Product>();
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入三条商品信息:");
        for(int i=0;i<3;){
            System.out.println("请输入第"+(i+1)+"条商品信息:");
            System.out.println("请输入商品编号:");
            String id=sc.next();
            //与hashset中元素不能重复类似,hashmap中键值不能重复,
            // 相同键值的元素只插入后面输入的一个
            //解决重复输入的隐患
            //判断输入的key值在当前的hashmap中是否存在
            if(map.containsKey(id)){
                System.out.println("该商品编号已存在,请重新输入");
                //退出当前循环,执行下一趟循环,i++放在循环末尾,
                // continue后面i++没有执行,不会影响循环次数
                continue;}
            System.out.println("请输入商品名称:");
            String name=sc.next();
            System.out.println("请输入商品价格:");
            //防止输入的参数不合法,捕获异常
            int price=0;
            try {
                //输入参数不合法时,nextInt报错,但输入的值已经存入for循环的下一个nextInt中,占据了下个元素的id值
                //因此在捕获异常的代码块中多写一个sc.next(),把错误的输入参数放进来,就不会占据下一个元素的id
                price = sc.nextInt();
            }catch (java.util.InputMismatchException e){
                System.out.println("商品格式不正确");
                sc.next();
                continue;
            };
            Product product1=new Product(id,name,price);
            map.put(id,product1);
            i++;
        }

        //遍历Map,输出商品信息
        Iterator<Product> it=map.values().iterator();
        while(it.hasNext())
            System.out.println(it.next());
        //与hashset中元素不能重复类似,hashmap中键值不能重复,相同键值的元素只插入后面输入的一个
        //解决重复输入的隐患
    }
}


class Product{
    private String id;
    private String name;
    private int price;

    @Override
    public String toString() {
        return "Product{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Product(String id,String name,int price) {
        this.id=id;
        this.name=name;
        this.price = price;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值