每日总结Day06

每日总结Day06


集合-Collection&List&Set

前言

今日主要学习了集合Collection以及List和Set等子类的特点、原理、应用场景等

一、集合体系

1.1.单列集合Collection

List:特点:有序、可重复
Set:特点:无序、不可重复

1.2.双列集合Map

二、Collection

2.1.常用方法

Collection 这是单列集合的根接口
boolean add(E e) 添加元素
boolean remove(E e) 删除指定的元素 (如有重复删除第一个)
boolean contains(Object obj) 判断集合中是否包含指定元素
int size() 返回集合中元素的个数
boolean isEmpty() 判断集合是否为空
Object[] toArray() 将集合中元素存入一个对象数组并返回
T[] toArray(T[]a) 将集合中元素存入一个指定类型的数组并返回(指定数组长度)
void clear() 清空集合
void addAll(集合) 添加另外一个集合中的元素

代码如下(示例):

//多态创建多列集合
Collection<String> collection1 = new ArrayList<>();
//boolean add(E e) 添加元素
collection1.add("刘备");
//boolean remove(E e) 删除指定的元素 (如有重复删除第一个)
collection1.remove("张三");
//boolean contains(Object obj) 判断集合中是否包含指定元素
boolean contains = collection1.contains("张三");
//int size() 返回集合中元素的个数
System.out.println(collection1.size());
//boolean isEmpty() 判断集合是否为空
System.out.println(collection1.isEmpty());
//Object[] toArray() 将集合中元素存入一个对象数组并返回
//Object[] array = collection1.toArray();
//T[] toArray(T[]a)  将集合中元素存入一个指定类型的数组并返回(指定数组长度)
String[] array = collection1.toArray(new String[collection1.size()]);
//void clear() 清空集合
//collection1.clear();

2.2.遍历1: 迭代器Iterator

单列集合专用遍历方式
Iterator相关方法
Iterator iterator() 获取迭代器对象,默认指向第一个元素
boolean hasNext() 断当前位置是否有元素可以取出 (有返回true,没有返回false)
E next() 返回当前位置的元素,并将送代器后移一位(如果没有元素可以取出了还继续取,会报NoSuchElementException)

固定格式
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String s = iterator.next();
}
代码如下(示例):

		//1. 准备一个集合
        Collection<String> collection = new ArrayList<>();
        collection.add("java");
        collection.add("python");
        collection.add("c++");
        collection.add("c#");

        //2. 获取迭代器对象
        Iterator<String> iterator = collection.iterator();
        //3. 使用迭代器遍历
        while (iterator.hasNext()){
            String next = iterator.next();
            System.out.println(next);
        }

2.3.遍历2: 增强for循环

数组和集合都可以使用

相关格式
for(元素数据类型 变量名 : 数组或者集合){
操作变量
}

注意
1. 在增强for循环中修改数据, 是不会影响数据源的(底层会创建临时变量,来记录容器中的数据)
2. 增强for遍历集合,底层是迭代器遍历集合的逻辑
3. 增强for遍历数组,底层是普通for循环的逻辑
代码如下(示例):

		//1. 准备一个集合
        Collection<String> collection = new ArrayList<>();
        collection.add("java");
        collection.add("python");
        collection.add("c++");
        collection.add("c#");

        //2. 使用增强for循环遍历
        for (String string : collection) {
            System.out.println("--");
            System.out.println(string);
        }
        //3. 打印原来的
        System.out.println(collection);

        //增强for循环也可以遍历数组
        int[] arr = {1,2,3};
        for (int i : arr) {
            System.out.println(i);
        }

2.4.遍历3: Lambda表达式方式遍历集合

相关格式
collection.forEach(e -> {
System.out.println(e);
});
代码如下(示例):

		//1. 准备一个集合
        Collection<String> collection = new ArrayList<>();
        collection.add("java");
        collection.add("python");
        collection.add("c++");
        collection.add("c#");

        //2. Lambda表达式方式遍历集合
        collection.forEach((str)->{
            System.out.println(str);
        });

2.5.并发修改异常

问题
使用迭代器遍历集合时,又同时在删除集合中的数据,程序就会出现并发修改异常的错误。
由于增强for循环遍历集合就是迭代器遍历集合的简化写法,因此,使用增强for循环遍历集合,又在同时删除集合中的数据时,程序也会出现并发修改异常的错误

解决方法
迭代器: 用迭代器自己的删除方法删除数据即可
增强for循环: 暂时无法解决
普通for循环:可以倒着遍历并删除;或者从前往后遍历,但删除元素后做i --操作。
代码如下(示例):

		//1. 准备一个集合
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("Java入门");
        arrayList.add("宁夏枸杞");
        arrayList.add("黑枸杞");
        arrayList.add("人字拖");
        arrayList.add("特级枸杞");
        arrayList.add("枸杞子");

        //删除所有带枸杞的
        Iterator<String> iterator = arrayList.iterator();
        while (iterator.hasNext()){
            String next = iterator.next();
            if(next.contains("枸杞")){
                iterator.remove();
            }
        }
        System.out.println(arrayList);

三、List集合

3.1.常用方法

List系列集合的特点
有序的, 可重复

List集合支持索引,所以提供了很多通过索引操作元素的方法
void add(int index,E e) 在此集合中的指定位置插入指定的元素
E remove(int index) 删除指定索引处的元素,返回被删除的元素 (一般不接收)
E set(int index,E e) 修改指定索引处的元素,返回被修改的元素(一般不接收)
E get(int index) 返回指定索引处的元素
代码如下(示例):

		List<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("王五");
        System.out.println(list);
        //void add(int index,E e) 在此集合中的指定位置插入指定的元素
        list.add(1,"赵六");
        System.out.println(list);
        //E remove(int index) 删除指定索引处的元素,返回被删除的元素 (一般不接收)
        list.remove(0);
        System.out.println(list);
        //E set(int index,E e) 修改指定索引处的元素,返回被修改的元素(一般不接收)
        list.set(0,"李四");
        System.out.println(list);
        //E get(int index) 返回指定索引处的元素
        System.out.println(list.get(0));

        System.out.println(list);

3.2.遍历方式

List支持的遍历方式
1. 迭代器
2. 增强for循环
3. Lambda表达式
4. for循环(因为List集合有索引)
代码如下(示例):

		List<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("王五");

        //1. 迭代器
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        System.out.println("==========================");
        //2. 增强for循环
        for (String s : list) {
            System.out.println(s);
        }
        System.out.println("==========================");
        //3. Lambda表达式
        list.forEach(s -> System.out.println(s));
        System.out.println("===========================");
        //4. for循环(因为List集合有索引)
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

3.3.1ArrayList

底层数据结构:
基于数组实现
特点:
1. 查询速度快(通过索引直接定位)
2. 增删效率低(增删的时候,需要移动增删元素后面的元素, 有时还需要进行扩容)
适用场景:
1. ArrayList适合于根据索引查询数据, 或者数据量不大的场景
2. ArrayList不适合于数据量大, 同时又要频繁进行增删操作的场景
底层原理:
1. 利用无参构造器创建的集合,会在底层创建一个默认长度为0的数组
ArrayList list = new ArrayList();
2. 添加第一个元素时,底层会创建一个新的长度为10的数组
list.add(“a”);
3. 存满时,会扩容1.5倍
比如存入第11个元素的时候, 长度会扩容到15
4. 如果一次添加多个元素, 1.5倍还放不下, 则新创建数组的长度以实际为准
比如原来是10个元素,现在又要存入10个, 则长度会扩容到20

3.3.2LinkedList

底层数据结构:
基于双向链表实现(内存地址不连续,每个元素记录自己的前后元素)
特点:
1. 查询速度慢
2. 增删效率高
3. 对于首尾元素进行增删改查的速度都是极快的
应用场景:
1. 用来设计队列(两端开口,类似于一个管道,先进先出)
只操作首尾元素, 尾部添加, 首部删除
2. 用来设计栈(一段开口,类似于弹夹,先进后出)
代码如下(示例):

	public static void main(String[] args) {
    	makeQueue();
    	//makeStack();
    }

    /*
        队列: 两端开口,特点是先进先出(排队)
        从队列后端入队列:  addLast 方法
        从队列前端出队列:  removeFirst方法
    */
    public static void makeQueue() {

        LinkedList<String> queue = new LinkedList<>();

        //从队列后端入队列: addLast方法
        queue.addLast("第1位顾客");
        queue.addLast("第2位顾客");
        queue.addLast("第3位顾客");
        queue.addLast("第4位顾客");
        System.out.println(queue);

        //从队列前端出队列: removeFirst方法
        System.out.println(queue.removeFirst());
        System.out.println(queue.removeFirst());
        System.out.println(queue);
        System.out.println("---------");
    }

    /*
        栈: 顶端开口的结构,特点是先进后出
        进栈/压栈: push方法(底层封装了addFirst 方法)
        出栈/弹栈: pop方法底 (底层封装了removeFirst方法)
    */
    public static void makeStack() {
        LinkedList<String> stack = new LinkedList<>();

        //进栈/压栈: push方法(底层封装了addFirst 方法)
        stack.push("第1颗子弹");
        stack.push("第2颗子弹");
        stack.push("第3颗子弹");
        stack.push("第4颗子弹");
        System.out.println(stack);

        //出栈/弹栈: pop方法底(底层封装了removeFirst方法)
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack);
    }

四、Set集合

4.1特点

Set系列集合的特点
无序, 不可重复

4.2.1HashSet

HashSet: 完美继承 、无序、没有索引、不可重复
代码如下(示例):

	//HashSet: 无序、没有索引、不可重复
    private static void testHashSet() {
        HashSet<Integer> hashSet = new HashSet<>();
        hashSet.add(44);
        hashSet.add(33);
        hashSet.add(11);
        hashSet.add(22);
        hashSet.add(22);
        System.out.println(hashSet);
    }

4.2.2LinkedHashSet

LinkedHashSet: 存取有序、存取有序、没有索引、不可重复
代码如下(示例):

	//LinkedHashSet: 存取有序、没有索引、不可重复
    private static void testLinkedHashSet() {
        LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>();
        linkedHashSet.add(44);
        linkedHashSet.add(33);
        linkedHashSet.add(11);
        linkedHashSet.add(22);
        linkedHashSet.add(22);
        System.out.println(linkedHashSet);
    }

4.2.3TreeSet

TreeSet: 可以排序、排序、没有索引、不可重复
代码如下(示例):

	//TressSet: 排序、没有索引、不可重复
    private static void testTreeSet() {
        TreeSet<Integer> treeSet = new TreeSet<>();
        treeSet.add(44);
        treeSet.add(33);
        treeSet.add(11);
        treeSet.add(22);
        treeSet.add(22);
        System.out.println(treeSet);
    }

4.3哈希值

就是一int值,Java每个对象都可以通过hashCode方法,获取自己的哈希值

哈希值特点
同一个对象多次调用hashCode方法,返回的哈希值是相同的;
不同的对象,他们哈希值大几率不相同,但是也有可能会相同(哈希碰撞)
Object的hashCode方法根据"对象地址值"计算哈希值,子类重写后的hashCode方法可以根据"对象属性值"计算哈希值

使用场景
HashSet集合判定两个对象的标准就是两个对象的hash值是否一致, 因此我们经常重写hashcode实现集合中对象去重

4.4HashSet集合的底层原理

DK8之前: 数组+链表
JDK8开始: 数组+链表+红黑树

树结构
二叉树: 基本模型
每一个根节点最多只能有两个子节点,子节点数量称为度,树的总层数为树高
左子节点
右子节点
左子树
右子树

二叉查找/二又搜索树: BST (Binary Search  Tree)
    小的存左边,大的存右边,相同则不存
    如果数据已经排好序,那么存入二又树查找树,会形成类似链表结构,查询效率还是低
    如果左、右子树的树高差比较大,那么导致左右子树不平衡,影响查询效率

平衡二叉树: AVL (Balanced  Binary Tree)
    有规律且相对平衡的二叉树
    当插入一个元素,导致左右子树的树高差大于1。那么就会触发旋转
    旋转分为左旋和右旋,用来保证左右子树的相对平衡

红黑: RBT (Red-Black  Tree)
    特殊的/自平衡的二又查找树,是计算机科学中用到的一种数据结构
    1972年出现时被称为平衡二叉树,后来1978年被修改为如今的红黑树
    红黑树不是高度平衡的,有自己保证平衡的规则(红黑规则),性能较好,红黑规则如下:
        每一个节点都是红色或者黑色的
        根节点必须是黑色的
        两个红色节点不能相连
        如果一个节点没有子节点,则该节点相应的指针属性为Nil (称为叶子结点),叶子结点是黑色的
        对于每一个节点,到其所有后代叶节点的简单路径上,包含的黑色 节点数量相同

4.5TreeSet的排序

对于数值型Integer、Double,默认按照数值升序排列;
对于String类型数据,默认按照字典排序
对于自定义类,默认是无法排序的,需要我们指定排序规则
自然排序:自定义类实现Comparable接口,重写compareTo方法,指定排序规则
比较器排序:写在TreeSet构造参数中传递Comparator比较器对象,重写compare方法,指定排序规则
需求
使用TreeSet存储教师对象,重复对象不存,并且用两种方式按照年龄升序排列

	public class Demo4 {

    public static void main(String[] args) {
        //创建TreeSet
        TreeSet<Teacher> treeSet = new TreeSet<>(new Comparator<Teacher>() {
            @Override
            public int compare(Teacher o1, Teacher o2) {
                return o1.getAge() - o2.getAge();
            }
        });

        //添加学生
        treeSet.add(new Teacher("张三", 19));
        treeSet.add(new Teacher("李四", 18));
        treeSet.add(new Teacher("王五", 20));
        treeSet.add(new Teacher("赵六", 17));
        treeSet.add(new Teacher("赵六", 17));

        //打印
        for (Teacher teacher : treeSet) {
            System.out.println(teacher);
        }
    }
}

class Teacher {
    private String name;
    private int age;



    public Teacher() {
    }

    public Teacher(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;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

总结

以上就是今天要的内容。

  • 26
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 通达信是一款常用的股票分析软件,其保存的日线数据文件格式为day文件。而csv文件是一种常见的数据文件格式,可以在不同的软件和工具之间交换和共享数据。 将通达信的day文件转换为csv文件可以通过以下步骤完成: 1. 打开通达信软件,并选择要转换的股票或指数的日线数据。 2. 在通达信软件中找到“导出”或“另存为”等选项,选择将数据导出为文本文件。 3. 在弹出的保存对话框中,选择保存为txt格式,以便后续处理。 4. 使用文本编辑器(如记事本、Sublime Text等)打开保存的txt文件。 5. 检查txt文件的格式,通达信的day文件通常包含日期、开盘价、最高价、最低价、收盘价等信息,每个数据之间用制表符或空格分隔。 6. 检查并调整txt文件的编码,确保其与要求的csv文件编码一致(如UTF-8)。 7. 在文本编辑器中选择“另存为”选项,并将文件格式选择为csv格式。 8. 保存文件,并选择适当的文件名和存储位置。 转换完成后,您就可以使用支持csv文件格式的软件(如Microsoft Excel、Python pandas库等)进行进一步的数据分析、可视化或处理。 需要注意的是,转换过程中可能需要根据具体的数据格式和软件要求进行一些调整和处理,例如处理日期格式、缺失值等。此外,如需处理多只股票或指数的数据,需要对每一个day文件进行转换。 ### 回答2: 通达信day文件是一种历史股票数据文件格式,包含了股票的高、低、开、收、成交量等信息。而CSV文件是一种以逗号分隔值的文本文件,用于储存简单的表格数据。如果想将通达信day文件转换为CSV文件,可以按照以下步骤操作。 首先,需要打开通达信软件,并选择要导出的历史数据。通达信软件提供了数据导出的功能,可以通过菜单或快捷键找到导出选项。 接下来,选择导出文件的路径和名称。通常可以选择将导出的CSV文件保存在本地计算机的某个文件夹中。 然后,在导出选项中选择CSV文件作为导出的文件格式。通常可以在导出选项中看到支持的文件格式,选择CSV文件即可。 最后,点击导出按钮,等待一段时间,通达信软件将会自动将day文件转换为CSV文件,并保存在之前选择的路径中。 转换完成后,可以在保存的路径中找到生成的CSV文件。可以使用文本编辑器或者电子表格软件打开CSV文件,查看其中的股票历史数据,包括日期、开盘价、收盘价、最高价、最低价等。 需要注意的是,不同版本的通达信软件可能略有差异,具体的操作步骤可能会有所不同。如果对于软件操作不熟悉,可以参考软件的帮助文档或者寻求专业人士的帮助。 ### 回答3: 通达信day文件是一种常见的股票数据文件格式,而CSV文件是一种常用的数据存储格式。将通达信day文件转换为CSV文件可以方便地对股票数据进行处理和分析。 通达信day文件通常以“day”为后缀名,包含股票的每日交易数据,如开盘价、收盘价、最高价、最低价、成交量等。而CSV文件以逗号分隔不同的数值,并且可以直接在电子表格软件中打开和编辑。 要进行转换,首先需要打开通达信软件,选择相应的股票数据文件。然后在数据菜单中选择“导出数据”选项,并选择CSV格式。接下来,在弹出的导出设置窗口中,可以选择需要导出的数据类型、导出起止日期等,并点击“确认”按钮。 此时,通达信软件会自动生成相应的CSV文件,保存在指定的路径下。打开生成的CSV文件,可以使用电子表格软件(如Excel)打开和编辑,方便进行数据处理和分析。在CSV文件中,每一行代表一条股票交易数据,各个数据字段以逗号分隔。 总结而言,将通达信day文件转换为CSV文件,可以通过通达信软件进行操作,选择导出数据的格式为CSV,然后软件会自动生成对应的CSV文件,方便进行后续的数据处理和分析。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值