java-learn(9):常见算法,collection框架

常见算法

collection

常用方法:

java 复制代码
 Collection<String> cl = new ArrayList<>();
        //boolean add()
        cl.add("abc");
        cl.add("bbb");
        cl.add("ccc");

        System.out.println(cl);

        cl.remove("abc");

        System.out.println(cl);

        //size()
        System.out.println(cl.size());

        boolean result = cl.contains("abc");
        System.out.println(result);

        boolean result1 = cl.isEmpty();
        System.out.println(result1);
        cl.clear();
        System.out.println(cl);

三种遍历的方式

迭代器

迭代器的细节:

1.如果当前位置没有元素,还要进行获取,会报NoSuchElementException

2.迭代器遍历完毕,指针不会复位

3.循环中只能用一次next方法

4.迭代器遍历时,不能使用集合的方法进行添加或者删除元素(如果实在要删除,只能使用迭代器的删除方法,添加还没有办法)

java 复制代码
//获取迭代器对象
 Iterator<String> it = cl.iterator();
        //it.hasNext() 判断当前位置是否有元素
        while(it.hasNext()){
            //得到当前位置的元素
            String str = it.next();
            System.out.println(str);
        }

增强for循环

java 复制代码
//语法
for(元素的数据类型 变量名:数组或者集合){

}
// 修改增强for中的变量,不会改变集合中原本的数据
//但是如果是可变对象 修改对象的属性间接修改对象的内容

lambda表达式遍历

java 复制代码
 coll.add("abc");
        coll.add("bcd");
        coll.add("fedg");
        //匿名内部类 
        coll.forEach(new Consumer<String>(){
           @Override
           public void accept(String s){
               System.out.println(s);
           } 
        });
        //lambda表达式
        coll.forEach(s->System.out.println(s));

三种表达式的使用场景:

当需要遍历删除元素时,可以使用迭代器的方式,当只需要遍历时,可以使用增加for循环,lambda表达式

List集合

java 复制代码
        list.add(1);
        list.add(2);
        list.add(3);
        System.out.println(list);

        //当方法重载时,优先调用实参更形参类型完全一致的那个方法
        list.remove(1);
        Integer i = Integer.valueOf(1);
        list.remove(i);
        System.out.println(list);
五中遍历方法对比:

迭代器遍历:删除元素

列表迭代器:需要添加元素,修改元素,删除元素

普通for遍历:需要使用到索引

增强for循环,lambda表达式遍历:只需要遍历,书写方式简单

java 复制代码
 //列表迭代器
        ListIterator<Integer> it1 = list.listIterator();
while(it1.hasNext()){
            Integer num = it1.next();
            if(num == 1){
                //迭代器添加元素是添加到当前位置的后一个位置,并指向添加后的那个元素
                it1.add(100);
            }else if(num == 10){
                //修改元素
                it1.set(1000);
            }
            if(num == 100){
                //删除元素
                it1.remove();
                System.out.println("遍历到了");
            }
        }

数据结构

ArrayList集合

在创建一个ArrayList的对象时,底层初始化的容量为0,当添加第一个元素的时候会进行扩容为10

在后面 如果容量不够会自动扩容为当前容量的1.5倍

但是还有就是可能会用到addAll去添加一个集合中的所有元素,这个时候就可能扩容1.5倍之后还不够,这个时候就会扩容为当前需要的容量

LinkedList集合

相当于双向连链表

泛型深入

在jdk5之前是没有泛型的,所有任意数据类型都可以存入到集合中,当遍历集合时,只能用object接受,但是这个不能使用子类特有的方法。在推出泛型之后,在指定的存入的数据类型之后就只能存入那种数据类型,避免了强制类型转化可能出现的异常

在指定泛型的具体类型之后,可以传入他对应的子类或者实现类的类型

没有指定泛型的时候,默认是object类型

泛型中不能写基本数据类型

java 复制代码
泛型类:

语法:
访问权限 class 类名<泛型>{}

如果不知道类型 可以默认设置一个为E
java 复制代码
泛型方法:
修饰符<类型>返回值类型 方法名(类型 变量名){}
例子:
public static<T> boolean addAll(ArrayList<T> list){};
java 复制代码
泛型接口:
写法和泛型类一样

泛型接口的使用:
1.实现类给出具体的类型
2.实现类延续泛型,创建对象时再确定泛型


java 复制代码
package Mycollection;

import java.util.ArrayList;

public class demo7 {

    public static void main(String[] args) {

        //泛型不能继承,但是数据可以继承
        ArrayList<Ye> list = new ArrayList<>();

        Fu f = new Fu();

        list.add(f);

        method(list);
    }

    //?也表示不确定的类型
    // 在不确定需要传入的数据类型时,可以使用泛型类,泛型接口,泛型方法
    // 如果类型不确定,但是知道具体的继承体系,就可与使用泛型的通配符
    // 通配符: 可以限定类型的范围 如果是? super E的话 就能传入当前类型以及他的父类
    // 如果是? extends E的话,只能传入当前类或者他的子类
    public static void method(ArrayList<? super Ye> t){

    }

}

class Ye{

}

class Fu extends Ye{

}

class Zi extends Fu{

}

set系列集合

java 复制代码
Set<String> myset = new HashSet<>();

        myset.add("abcd");
        myset.add("bbb");
        myset.add("ccc");
        myset.add("ooo");

        System.out.println(myset.add("acbd"));

        System.out.println(myset.add("acbd"));
        // 增强for循环遍历
        for(String s : myset){
            System.out.println(s);
        }
        // contains
        System.out.println(myset.contains("acbd"));
        // remove
        System.out.println(myset.remove("acbd"));
        System.out.println(myset.size());
        System.out.println(myset);
        System.out.println(myset);

        // 迭代器的遍历
        Iterator<String> it = myset.iterator();

        while(it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }
        //lambda表达式
        myset.forEach(new Consumer<String>(){
            @Override
            public void accept(String s){
                System.out.println(s);
            }
        });

        //简略版
        myset.forEach(s-> System.out.println(s));
        myset.forEach(System.out::println);

hashset

数组+链表+红黑树

hashSet底层原理:

在jdk8之后,当链表长度大于八,而且数组长度等于64时,自动转化为红黑树

如果集合中储存的是自定义对象,必须重写hashCode和equals方法,重写hashCode是为了用对象的属性值去进行计算哈希值,重写equals是为了用对象的属性值进行比较。

linkedhashset


TreeSet

TreeSet的特点:可以排序,无索引,不重复

如果是String,Integer默认是从小到大排序

如果是自定义类型 需要重写compareTo方法

第一种比较方式

java 复制代码
 @Override
    public int compareTo(Student o) {
        //o代表的是已经存入到红黑树中的元素
        //结果返回负数代表需要存储在o的左边
        //为正数代表需要存入到o的右边
        //为0的话就代表有相同的对象,就不会存入到红黑树中
        return this.getAge() - o.getAge();
    }

第二种比较方式

java 复制代码
  //比较器排序
        TreeSet<String> t = new TreeSet<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                int temp = o1.length() - o2.length();
                return temp == 0 ? o1.compareTo(o2) : temp;
            }
        });
        t.add("a");
        t.add("bc");
        t.add("ff");
        t.add("jfjf");
        System.out.println(t);

综合案例,使用场景

相关推荐
nbsaas-boot8 小时前
SaaS 租户上下文传播架构
java·架构·saas
岑梓铭8 小时前
《考研408数据结构》第七章(6.1~6.3图的概念、存储方式、深/广度遍历)复习笔记
数据结构·笔记·考研·算法·图论·408·ds
西岭千秋雪_8 小时前
Zookeeper监听机制
java·linux·服务器·spring·zookeeper
脏脏a8 小时前
【C++ 入门】:引用、内联函数与 C++11 新特性(auto、范围 for、nullptr)全解析
开发语言·c++
毕设源码-林学长8 小时前
计算机毕业设计java和Vue的安全教育科普平台设计与实现 安全知识普及与教育平台 安全教育信息化管理平台
java·开发语言·课程设计
ruleslol8 小时前
java-接口适配器模式 & jsk8 接口默认实现
java·适配器模式
恒者走天下8 小时前
cpp / c++零基础就业学习一站式学习平台
开发语言·c++·学习
Python私教8 小时前
Rust 编程语言基础知识全面介绍
开发语言·后端·rust
鬼火儿8 小时前
网卡驱动架构以及源码分析
java·后端