List、 Set、 数据结构、可变参数、Collections

数据结构

当你用着java里面的容器类很爽的时候,你有没有想过,怎么ArrayList就像一个无限扩 充的数组,也好像链表之类的。好用吗?好用,这就是数据结构的处,只不过你在不知不觉中使用了。

现实世界的存储,我们使用的工具和建模。每种数据结构有自己的优点和缺点,想想如果Google的数据用的是数组的存储,我们还能方便地查询到所需要的数据吗?而算法,在这么多的数据中如何做到最快的插入,查找,删除,也是在追求更快。

我们java是面向对象的语言,就好似自动档轿车, C语言好似手动档吉普。数据结构呢?题速箱的工作原理。你完全可以不知道变速箱怎样工作,就把自动档的车子从A点开到B点,且未必就比懂得的人慢。写程序这件事,开车-样,经验可以起到很大作用,但如果你不知道底层是怎么工作的,就永远只能开车,既不会修车,也不能造车。当然了,数据结构内容比较多,细细的学起来也是相对费功夫的,可能达到一蹴而就。我们将常见的数据结构:堆栈、队列、数组、链表和红黑树几种给大家介绍一 下,作为数据结构的入门,了解- -下它们的特点即可。

栈(stack)

栈思维导图轩成笔记

队列(queue)

队列思维导图轩成笔记

数据结构----数组与链表结构

数组:增删慢,查询块
链表:查询慢,易于增删
单项链表只有两个部分,自己的地址和数据,他这样画错了。
双向链表有三部分,自己的地址和数据以及下一个节点的 地址
在这里插入图片描述

数据结构----树

二叉树与查找树/排序树

二叉树分支不能超过两个
排序树/查找树:在二叉树的基础上,元素大小有顺序的:左子树小,右子树大
在这里插入图片描述

平衡树与不平衡树

在这里插入图片描述

红黑树

红黑树:
特点:趋近于平衡树,查询的速度非常快
约束:
1.节点可以是红色或者黑色的
2.根节点是黑色的
3.叶子节点(空节点)是黑色的
4.每个红色节点的子节点必须都是黑色的
5.任何-个节点到其每个叶子节点的所有路径
.上的黑色节点数相同
在这里插入图片描述

List集合

List接口:
特有的方法:
void add(int index,E element): 将指定元素,添加到该集合中指定位置
E get(int index)返回此列表中指定位置的元素。
E set(int index,E element)用指定的元素(可选操作)替换此列表中指定位置的元素。


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/*List接口:
特有的方法:
void add(int index,E element): 将指定元素,添加到该集合中指定位置
E get(int index)返回此列表中指定位置的元素。
E set(int index,E element)用指定的元素(可选操作)替换此列表中指定位置的元素。
*/
public class LsitTest01 {
    public static void main(String[] args) {
        List<String> list=new ArrayList<>();//多态
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("e");
        System.out.println(list);//这里输出不是地址,因为重写了tostring
        list.add(1,"hello World");//void add(int index,E element): 将指定元素,添加到该集合中指定位置
        list.set(0,"123");//E get(int index)返回此列表中指定位置的元素。
        //for循环遍历
        for (int i = 0; i <list.size() ; i++) {
            System.out.print(list.get(i));
        }
        System.out.println();
        //迭代器遍历
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            System.out.print(it.next());
        }
        System.out.println();
        //增强for遍历
        for (String s : list) {
            System.out.print(s);
        }
    }
}

常见面试笔试题Arraylist,LinkedList,Vector的区别

在这里插入图片描述

LinkedList集合

特点
1.链表结构,查询慢,增删快
2.API中包含了很多操作首尾元素的方法
特有方法:
public void addFirst(E e)在该列表开头插入指定的元素。
public void addLast(E e)将指定的元素追加到此列表的末尾。
public E getFirst()返回此列表中的第一 个元素。
public E getLast()返回此列表中的最后一 个元素。
public E removeFirst()从此列表中删除并返回第一 个元素。
public E removeLast()从此列表中删除并返回最后一 -个元素。
public void push(E e) 将元素推送到由此列表表示的堆栈上。换句话说,在该列表的前面插入元素。
此方法相当FaddFirst(E)。
public E pop()从此列表表示的堆栈中弹出一 个元素。 换句话说,删除并返回此列表的第一 个元素。
此方法相当FremoveFirst()。

import java.util.LinkedList;

/*LinkedList集合
特点
1.链表结构,查询慢,增删快
2.API中包含了很多操作首尾元素的方法
特有方法:
public void addFirst(E e)在该列表开头插入指定的元素。
public void addLast(E e)将指定的元素追加到此列表的末尾。
public E getFirst()返回此列表中的第一 个元素。
public E getLast()返回此列表中的最后一 个元素。
public E removeFirst()从此列表中删除并返回第一 个元素。
public E removeLast()从此列表中删除并返回最后一 -个元素。
public void push(E e) 将元素推送到由此列表表示的堆栈上。换句话说,在该列表的前面插入元素。
此方法相当FaddFirst(E)。
public E pop()从此列表表示的堆栈中弹出一 个元素。 换句话说,删除并返回此列表的第一 个元素。
此方法相当FremoveFirst()。
*/
public class ListTest02 {
    public static void main(String[] args) {
        show01();
        show02();
    }

    private static void show02() {
        LinkedList<String> list = new LinkedList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        System.out.println(list.removeFirst());
        System.out.println(list.removeLast());
        System.out.println(list);
        list.push("www");
        System.out.println(list);
        list.pop();
        System.out.println(list);

    }

    private static void show01() {
        LinkedList<String> list = new LinkedList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        System.out.print(list);
        System.out.println();
        list.addFirst("w");
        list.addLast("d");
        System.out.print(list);//[w, a, b, c, d]
        System.out.println(list.getFirst());
        System.out.println(list.getLast());
        System.out.println("++++++++");
    }
}

set集合

HashSet

package demo02;

import java.util.HashSet;
import java.util.Set;

/*
* set特点
* 1.不允许重复
* 2.没有索引,普通for循环不能使用
* HashSet类特点:
1.不允许存储重复的元素
2.没有索引,也没有带索引的方法,也不能使用普通for循环
3.是个无序的集合,存储和取出元素的顺序可能不同
4.底层是-一个哈希表(查询速度非常快)
*/
public class SetTest01 {
    public static void main(String[] args) {
       Set<Integer> list = new HashSet<>();
       list.add(1);
        list.add(2);
        list.add(1);
        list.add(3);
        for (Integer integer : list) {
            System.out.println(integer);
        }
        Set<String> list1 = new HashSet<>();
        String a1 = new String("abc");
        //set1集合调用add方法的时候会自动调用元素的hashCode() equals()方法,判断元素是否重复
        String a2 = new String("abc");
        list1.add(a1);
        list1.add(a2);
        list1.add("重地");
        list1.add("通话");
        list1.add(a1);
        System.out.println(a1.hashCode());//96354
        System.out.println(a2.hashCode());//96354
        System.out.println("重地".hashCode());//1179395
        System.out.println("通话".hashCode());//1179395
        for (String s : list1) {
            System.out.println(s);//重地通话abc
        }
    }
}

哈希表

在这里插入图片描述

哈希冲突

当哈希值是一样的时候时会出现哈希冲突,这时候调用equals方法判断是否是true如果是true,那么就不会加入集合,如果是false那么会加入集合。

HashSet存储自定义元素类型:

要求:自定义类需要重写hashCode equals方法

import java.util.HashSet;

public class SetTest02 {
    public static void main(String[] args) {
        HashSet<Person> list = new HashSet<>();
        list.add(new Person("大",8));
        list.add(new Person("大",18));
        list.add(new Person("大",8));
        /*没有重写hashcode之前
         * [Person{name='大', age=18}, Person{name='大', age=8}, Person{name='大', age=8}]*/
        System.out.println(list);
        /*重写之后
         * [Person{name='大', age=18}, Person{name='大', age=8}]*/
    }
}
import java.util.Objects;

public class Person {
    String name;
    int age;

    public Person(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 boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

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

LinkedHashSet:

LinkedHashSet:特点:
底层是哈希表(数组+链表+红黑树) +链表:
多了一条链表是用来记录元素的存储顺序的
保证元素有序
元素不能重复

import java.util.LinkedHashSet;

public class SetTest03 {
    public static void main(String[] args) {
        LinkedHashSet<String> list = new LinkedHashSet<>();
        list.add("中");
        list.add("大");
        list.add("小");
        list.add("钱");
        list.add("中");
        /*for (String s : list) {
            System.out.println(s);
        }*/
        System.out.println(list);
    }
}

可变参数

可变参数:是JDK1. 5之后出现的新特性
使用前提:当方法的参数列表中数据类型已经确定, 但是参数个数不确定,就可以使用可变参数
使用格式:定义方法时使用
修饰符返回值方法名(数据类型…变量名) {
可变参数底层就是个数组

注意事项:
1)一一个方法的参数列表只能有一-个可变参数
2)如果参数列表的参数有多个,那么可变参数一-定要写在末尾

package demo03;
/*
* 可变参数:是JDK1. 5之后出现的新特性
使用前提:当方法的参数列表中数据类型已经确定, 但是参数个数不确定,就可以使用可变参数
使用格式:定义方法时使用
修饰符返回值方法名(数据类型...变量名) {
可变参数底层就是个数组
*
* 注意事项:
1)一一个方法的参数列表只能有一-个可变参数
2)如果参数列表的参数有多个,那么可变参数一-定要写在末尾
* */
public class VarArgsTest {
    public static void main(String[] args) {
        int sum = add(1, 3, 6, 5, 9, 5, 1);
        System.out.println(sum);
        String s = add1("xuancheng", 1, 3, 6, 5, 9, 5, 1);
        System.out.println(s);
    }
    public static String add1(String n,int...arr) {
        int sum=0;
        for (int i : arr) {
            sum+=i;
        }
        return sum+n;
    }

    public static int add(int...arr) {
        int sum=0;
        for (int i : arr) {
            sum+=i;
        }
        return sum;
    }

}

Collections

Collections:
public static <T extends Comparable<? super T>> void sort(List list) 按照升序排列指定的列表
前提:被排序的集合里边存储的元素,必须实现Comparable接口,并且重写接口中CompareTo()方法
定义比较规则:
return this. age-o. age;//升序
return o. age-this. age;//降序

import java.util.ArrayList;
import java.util.Collections;

import demo02.Person;

import java.util.ArrayList;
import java.util.Collections;

/*Collections:
public static <T> boolean addALl(Collection<? super T> c, T... elements) 将所有指定的元素添加到指定的集合。
public证static void shuffle(List<?> list) 使用默认的随机源随机排列指定的列表
*/
public class CollectionsTest01 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"a","b","c","d");
        System.out.println(list);//[a, b, c, d]
        Collections.shuffle(list);
        System.out.println(list);//[b, a, c, d]
        ArrayList<Person> list1 = new ArrayList<>();
        Collections.addAll(list1,new Person("战士",18),new Person("李四",20));
        Collections.sort(list1);
        System.out.println(list1);
    }
}



import java.util.Objects;

public class Person implements Comparable<Person> {
    String name;
    int age;

    public Person(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 boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

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



    @Override
    public int compareTo(Person o) {
        return this.age-o.age;//升序
        //o.age-this.age//逆序
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

轩成笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值