集合1

集合

Collection:
    - List: 元素有序且允许发生重复,有索引
        - ArrayList: 底层数据结构是数组,查询快,增删慢
        - Vector
        - LinkedList
    - Set:

例子:

public class ArrayListDemo1 {
    public static void main(String[] args) {
        ArrayList list1 = new ArrayList();

        list1.add("hello");
        list1.add("world");
        list1.add("hello");
        list1.add("java");
        list1.add("flink");

        Iterator iterator = list1.iterator();
        while (iterator.hasNext()){
            Object o = iterator.next();
            System.out.println(o);
        }
    }
}

链表:

 Collection:
        - List: 元素有序且允许发生重复,有索引
            - ArrayList: 底层数据结构是数组,查询快,增删慢,线程不安全的,效率高
            - Vector: 底层数据结构是数组,查询快,增删慢,线程安全的,效率低,即便是这样,我们以后也不用
            - LinkedList: 底层数据结构是双链表,增删快,查询慢,线程不安全,效率高
        - Set:

LinkedList:特有的功能

LinkedList类特有功能【由于底层是链表】
        public void addFirst(Object e)及addLast(Object e)
        public Object getFirst()及getLast()
        public Object removeFirst()public Object removeLast()

例子:

public class LinkedListDemo1 {
    public static void main(String[] args) {
        //LinkedList() 构造一个空列表。
        LinkedList list1 = new LinkedList();

        list1.add("hello");
        list1.add("world");
        list1.add("hello");
        list1.add("clickhouse");
        list1.add("redis");

        System.out.println("list1: "+list1);

//        Iterator iterator = list1.iterator();
//        while (iterator.hasNext()){
//            System.out.println(iterator.next());
//        }

        System.out.println("-----------------------------------------");
        //public void addFirst(Object e)及addLast(Object e) 在头部添加一个元素或者尾部添加元素
        list1.addFirst("kafka");
        list1.addLast("cdh");
        System.out.println("list1: "+list1);

        //public Object getFirst()及getLast()
        System.out.println(list1.getFirst());
        System.out.println(list1.getLast());
        System.out.println("list1: "+list1);

        //public Object removeFirst()及public Object removeLast() 从集合中移除第一个元素或最后一个元素
        System.out.println(list1.removeFirst());
        System.out.println(list1.removeLast());
        System.out.println("list1: "+list1);


    }
}

练习:

去除集合中字符串的重复值(字符串的内容相同)
去除集合中字符串的重复值(字符串的内容相同)
public class ArrayListTest1 {
    public static void main(String[] args) {
        ArrayList list1 = new ArrayList();

        list1.add("hello");
        list1.add("world");
        list1.add("hello");
        list1.add("java");
        list1.add("flink");
        list1.add("hello");
        list1.add("java");
        list1.add("world");
        list1.add("hello");
        System.out.println("list1: "+list1);
        System.out.println("----------------------------");
        //创建一个新的集合,遍历旧集合
        //如果新集合中有该元素,说明重复,不添加
        //反之添加到新集合中,最后新集合中存储去重后的结果
        ArrayList list2 = new ArrayList();

        Iterator iterator = list1.iterator();
        while (iterator.hasNext()){
            String s = (String) iterator.next();
            if(!list2.contains(s)){
                list2.add(s);
            }
        }

        System.out.println("list2: "+list2);


    }
}

去除集合中自定义对象的重复值(对象的成员变量值都相同)
去除集合中自定义对象的重复值(对象的成员变量值都相同)
public class ArrayListTest2 {
    public static void main(String[] args) {
        ArrayList list1 = new ArrayList();

        Student s1 = new Student("张成阳", 18);
        Student s2 = new Student("方直", 19);
        Student s3 = new Student("张成阳", 18);
        Student s4 = new Student("方直", 19);
        Student s5 = new Student("张成阳", 18);
        Student s6 = new Student("方直", 19);

        list1.add(s1);
        list1.add(s2);
        list1.add(s3);
        list1.add(s4);
        list1.add(s5);
        list1.add(s6);

        System.out.println("list1: "+list1);
        System.out.println("----------------------------");

        //创建一个新的集合,遍历旧集合
        //如果新集合中有该元素,说明重复,不添加
        //反之添加到新集合中,最后新集合中存储去重后的结果


        ArrayList list2 = new ArrayList();

        Iterator iterator = list1.iterator();
        while (iterator.hasNext()){
            Student s = (Student) iterator.next();
            if(!list2.contains(s)){
                list2.add(s);
            }
        }
        /*
            我们按照去重字符串的逻辑对学生对象进行去重,发现不太行
            旧集合中的每一个学生对象都添加到了新集合中‘
            从结果来看。每一个学生对象41行的判断【!list2.contains(s)】都是true
            list2.contains(s) 一直都是false
            要想知道为什么list2.contains(s)一直都是false的话,就应该去看contains的源码

            public boolean contains(Object o) {
                // o - new Student("张成阳", 18);
                return indexOf(o) >= 0;
            }

            public int indexOf(Object o) {
            // o - new Student("张成阳", 18);
                if (o == null) {
                    for (int i = 0; i < size; i++)
                        if (elementData[i]==null)
                            return i;
                } else {
                    for (int i = 0; i < this.size; i++) // 遍历新集合,调用元素的equals方法挨个与新集合中的元素进行比较
                        if (o.equals(elementData[i]))
                            return i; // i的值一定是大于等于0
                }
                return -1;
            }

            从源码上来看,底层是调用了元素类型中的equals方法,而我们的元素是学生类,学生类中没有重写该方法,用的是父类Object类中的
            equals方法,比较的是地址值,而每一学生都是new出来的,地址肯定不一样。
            解决方案:元素类型中重写equals方法即可
         */


        System.out.println("list2: "+list2);
    }
}

请用LinkedList模拟栈数据结构的集合,并测试。栈的特点:先进后出
请用LinkedList模拟栈数据结构的集合,并测试
    栈的特点:先进后出

    题目的意思是:自己造一个类,底层封装LinkedList,自己定义方法
    创建自己的类对象,调用自己定义的方法,来实现栈。

解:

import java.util.LinkedList;

public class MyStack {
    private LinkedList list;
    public MyStack(){
        list = new LinkedList();
    }

    public void shuJiaAddElement(Object o){
        list.addFirst(o);
    }

    public Object shuJiaGetElement(){
        return list.removeFirst();
    }

    public int getSize(){
        return list.size();
    }

    @Override
    public String toString() {
        return "MyStack{" +
                "list=" + list +
                '}';
    }
}




public class LinkedListTest1 {
    public static void main(String[] args) {
        MyStack myStack = new MyStack();
        myStack.shuJiaAddElement("hello");
        myStack.shuJiaAddElement("world");
        myStack.shuJiaAddElement("java");
        myStack.shuJiaAddElement("hello");
        myStack.shuJiaAddElement("hadoop");

        System.out.println("myStack: " + myStack);

        int size = myStack.getSize();
        for (int i = 0; i < size; i++) {
            System.out.println(myStack.shuJiaGetElement());
        }


    }
}

泛型

回忆下,在此之前,我们的集合可以存放任意类型的元素,但是实际开发的时候,一个集合规定只允许放一种数据类型的元素
java中的集合提供了一种类似于数组定义时确定元素类型的方式,泛型
泛型:
        语句定义格式:<引用数据类型>
        将引用数据类型当作参数一样传递

泛型的好处:

泛型的好处:
        1、减少了程序中的黄色警告
        2、遍历的时候不需要再做向下转型了,因为在创建集合对象的时候,给定了泛型的类型

public class FanXingDemo1 {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>(); // 泛型定义了集合中的元素数据类型,右边的尖括号泛型可以不写,自动类型推断
//        ArrayList list1 = new ArrayList();
//        list1.add()
//        list1.add(10);
        list1.add("hello");
        list1.add("world");
        list1.add("java");
        list1.add("hadoop");
        list1.add("world");
        list1.add("hello");
        list1.add("flink");
//        list1.add(false);
        System.out.println("list1: "+list1);
        System.out.println("----------------------------");

        Iterator<String> iterator = list1.iterator();
        while (iterator.hasNext()){
            String s = iterator.next();
            System.out.println(s+"-"+s.length());
        }


    }
}

泛型将来遇到的场景

泛型类:将泛型定义在类上
     <>里面的参数是为了将来调用时接收传入的引用数据类型,相当于一个形参一样,符合变量标识符命名规则就可以了
    但是规范来说,泛型的名字,由一个大写的英文字母表示
class Demo1<A>{
    public void fun1(A a){
        System.out.println(a);
    }
}

public class FanXingDemo2 {
    public static void main(String[] args) {
        Demo1<Integer> stringDemo1 = new Demo1<>();
        stringDemo1.fun1(100);
//        stringDemo1.fun1("hello");

        Demo1<String> d2 = new Demo1<>();
        d2.fun1("hello");
//        d2.fun1(100);


    }
}

把泛型定义在方法上 格式:public <泛型类型> 返回类型 方法名(泛型类型 .)

class Demo2<Q>{
    public <E> void fun1(E e){
        System.out.println(e);
    }

    public void fun2(Q q){
        System.out.println(q);
    }
}
public class FanXingDemo3 {
    public static void main(String[] args) {
        Demo2<Double> demo2 = new Demo2<>();
        demo2.fun1("hello");
        demo2.fun1(100);

        demo2.fun2(12.34);
    }
}

泛型接口

把泛型定义在接口上,格式:public interface 接口名<泛型类型1…>
interface Inter<W>{
    void fun1(W w);
}

class InterImpl<W> implements Inter<W>{
    @Override
    public void fun1(W w) {
        System.out.println(w);
    }
}

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


    }
}

泛型通配符<?>

  任意类型,如果没有明确,那么就是Object以及任意的Java类了
? extends E
   向下限定,E及其子类
? super E
   向上限定,E及其父类
class Animal {

}

class Dog extends Animal {

}

class Cat extends Animal {

}

class Demo3 {
    public void fun1(Collection<?> c1) { // 可以接收元素是任意引用数据类型的Collection集合对象
        System.out.println("c1: " + c1);
    }

    public void fun2(Collection<? extends Animal> c1) { // 可以接收元素是Animal类型或Animal的子类类型的的Collection集合对象
        System.out.println("c1: " + c1);
    }

    public void fun3(Collection<? super Animal> c1) { // 可以接收元素是Animal类型或Animal的父类类型的的Collection集合对象
        System.out.println("c1: " + c1);
    }



//    public void fun1(Xxxx<?> c1) { // 可以接收元素是任意引用数据类型的Xxxx对象
//        System.out.println("c1: " + c1);
//    }
}

public class FanXingDemo5 {
    public static void main(String[] args) {
        Demo3 d1 = new Demo3();
        ArrayList<Animal> list1 = new ArrayList<>();
        ArrayList<Dog> list2 = new ArrayList<>();
        ArrayList<Cat> list3 = new ArrayList<>();
        ArrayList<Object> list4 = new ArrayList<>();
        //Collection<?> c1
        d1.fun1(list1);
        d1.fun1(list2);
        d1.fun1(list3);
        d1.fun1(list4);


        d1.fun2(list1);
        d1.fun2(list2);
        d1.fun2(list3);
//        d1.fun2(list4);


        d1.fun3(list1);
//        d1.fun3(list2);
//        d1.fun3(list3);
        d1.fun3(list4);


        //public boolean addAll(Collection<? extends Animal> c)
        ArrayList<Animal> animals = new ArrayList<>();
        animals.addAll(list1);
        animals.addAll(list2);
        animals.addAll(list3);
//        animals.addAll(list4);
    }
}

一些小知识点

增强for循环:
        是用来代替迭代器的,可以遍历数组和Collection集合

    语句定义格式:
        for(元素的数据类型 变量名 : 数组或Collection集合){
            使用变量名;
        }

例子

public class ZengForDemo {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();

        list1.add("hello");
        list1.add("world");
        list1.add("java");
        list1.add("hadoop");
        list1.add("world");
        list1.add("hello");
        list1.add("flink");
        System.out.println("list1: "+list1);
        System.out.println("----------------------------");

        for (String s : list1) {
            System.out.println(s + "-" + s.length());
        }
//
//        for (String s : list1) {
//            System.out.println(s + "-" + s.length());
//        }

        System.out.println("----------------------------");

        int[] arr = {11,22,33,44,55};
        for(int i : arr){
            System.out.println(i);
        }
    }
}

导入方法例:max

package shujia.day10;
//import static java.lang.Math.max;
//import static java.lang.Math.min;

import static java.lang.Math.*;

public class StaticImportDemo {
    public static void main(String[] args) {
//        System.out.println(Math.max(12,34));
//        System.out.println(Math.max(23,1));
//        System.out.println(Math.max(42,51));
//        System.out.println(Math.max(12,124));


        System.out.println(max(123, 5));
//        System.out.println(min(213, 6));
        System.out.println(Math.max(123,5));
    }

    public static int max(int a, int b) {
        return a + b;
    }
}

可变参数:

    语句定义格式:数据类型... arr
注意事项
注意事项:
        1、方法定义时,如果有可变参数,可变参数必须在最后一个定义
        2、一个方法定义时,只能有一种类型是可变参数

例子:

public class KeBianCanDemo1 {
    public static void main(String[] args) {
//        //需求:求两个int数之和
//        int a = 3;
//        int b = 4;
//        sum(a, b);
//
//        //需求:求三个int数之和
//        int c = 5;
//        sum(a, b, c);
//        //需求:求n个int数之和
//        int d = 6;
//        sum(a,b,c,d);

        //调用方法,传入一个学生的姓名和若干门成绩
        stuScore("zcy",89,98);
        stuScore("fz",99,78,91);

        //可变参数使用的例子
        List<String> list = Arrays.asList("hello", "world", "hello", "java", "hadoop");


    }

    public static void stuScore(String name, int... scores){
        int sum = 0;
        for (int i : scores) {
            sum+=i;
        }
        System.out.println("姓名:"+name+"总成绩:"+sum);
    }

    public static void sum(int... arr) { // 可以传入若干个int类型的值,被封装到了一个数组中,数组的名字叫做arr
//        System.out.println(a + b);
        int sum = 0;
        for (int i : arr) {
            sum+=i;
        }
        System.out.println(sum);
    }


//    public static void sum(int a, int b, int c) {
//        System.out.println(a + b + c);
//    }
//
//    public static void sum(int a, int b) {
//        System.out.println(a + b);
//    }
}

posted @   09250327  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示