首页 > 编程语言 >java集合

java集合

时间:2025-01-17 23:34:21浏览次数:1  
标签:java list1 System println add 集合 public out

集合

想一下,目前为止,我们学过哪些可以存储元素的容器:
1、数组,查询快,增删慢。
既可以存储基本数据类型的元素,又可以存储引用数据类型的元素
对于同一个数组而言,元素类型都是一样
长度一旦创建旧固定了,不能改变长度。

2、StringBuffer
长度可以随着添加的字符个数而改变
StringBuffer容器中的元素就一种类型,字符类型

针对不同的数据结构,存储方式以及取出方式不同,java提供了许多不同种类特点的容器【集合】
也就是java是通过类去描述一个事物的,不同的容器,也会提供不同的集合类

Collection【接口】:
- List【接口】:
- ArrayList【子类】

借助实现类:ArrayList学习Collection接口中的方法
ArrayList类中的构造方法:
ArrayList() 构造一个初始容量为十的空列表。

学习任意集合的步骤:
1、创建集合对象
2、创建元素对象
3、将元素对象放入到集合中
4、遍历集合

集合关系图

Java 集合可分为 Collection 和 Map 两种体系:

  • Collection接口:单列数据,定义了存取一组对象的方法的集合

    • List:元素有序、可重复的集合
    • Set:元素无序、不可重复的集合
  • Map接口:双列数据,保存具有映射关系“key-value对”的集合

集合面试提问

  • 为什么出现集合类?
    面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,Java就提供了集合类。
  • 数组和集合类同是容器,有何不同?
    数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。
  • 集合类的特点
    集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象

Collection接口及方法

  • Collection 接口是 List、Set 和 Queue 接口的父接口,该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。

    Collection接口中的方法:
        boolean add(Object e)
        boolean remove(Object o)
        void clear()
        boolean contains(Object o)
        boolean isEmpty()
        int size()
    
public class CollectionDemo1 {
    public static void main(String[] args) {
        Collection c1 = new ArrayList();
        System.out.println("c1: " + c1);

        // boolean add(Object e) 向集合中添加元素
        c1.add(10); // 自动装箱,将int类型的值封装成包装类对象
        c1.add(12.34);
        c1.add(true);
        c1.add("hello");
        System.out.println("c1: " + c1);

        //[10, 12.34, true, hello]
        //boolean remove(Object o) 从集合中移除某一个元素
        c1.remove(100);
        System.out.println("c1: " + c1);

        //void clear() 将集合中元素清空
//        c1.clear();
//        System.out.println("c1: " + c1);

        //boolean contains(Object o) 判断集合中是否包含某个类型的元素
        System.out.println(c1.contains("hello"));

        //boolean isEmpty() 判断集合中是否有元素存在
        System.out.println(c1.isEmpty());

        //int size() 获取集合中元素的个数【集合的长度】
        System.out.println(c1.size());

    }
}
/*
    Collection中的方法:
        boolean addAll(Collection c)
        boolean removeAll(Collection c)
        boolean containsAll(Collection c)
        boolean retainAll(Collection c)

 */
public class CollectionDemo2 {
    public static void main(String[] args) {
        // 借助子类ArrayList创建Collection集合
        Collection c1 = new ArrayList();
        c1.add(11);
        c1.add(22);
        c1.add(33);
        c1.add(44);
        System.out.println("c1: " + c1);

        Collection c2 = new ArrayList();
        c2.add(33);
        c2.add(44);
        c2.add(55);
        c2.add(66);
        System.out.println("c2: " + c2);
        System.out.println("-----------------------------");
        //boolean addAll(Collection c) 将另一个集合中的元素批量添加
        c1.addAll(c2);
        System.out.println("c1: "+c1);
        System.out.println("c2: "+c2);
        System.out.println("-----------------------------");
//        boolean removeAll(Collection c) 从一个集合中移除另一个集合所有的元素
        c1.removeAll(c2);
        System.out.println("c1: "+c1);
        System.out.println("c2: "+c2);
        System.out.println("-----------------------------");
        //boolean containsAll(Collection c) 判断A集合中是否完整包含集合B中的元素
        System.out.println(c1.containsAll(c2));
        System.out.println("-----------------------------");
        //boolean retainAll(Collection c)
//        c1.retainAll(c2);
        c2.retainAll(c1);
        System.out.println("c1: " + c1);
        System.out.println("c2: " + c2);


    }
}

遍历集合

增强for循环

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

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

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

        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());
        }
//        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);
        }
        }
    }

如何遍历一个Collection集合,得到每一个元素。

Object[] toArray()

把集合转成数组,可以实现集合的遍历

public class CollectionDemo3 {
    public static void main(String[] args) {
        Collection c1 = new ArrayList();
        c1.add("hello");
        c1.add("world");
        c1.add("java");
        c1.add("hadoop");
        System.out.println("c1: " + c1);
        System.out.println("-------------------------");
        Object[] array = c1.toArray();
        for (int i = 0; i < array.length; i++) {
            // array[i] - "java"
            // Object o = "java";
//            System.out.println("元素:"+array[i]);
            //此时,这里需要进行向下转型才可以使用元素自身类型中的方法
            String s = (String) array[i];
            System.out.println("元素:" + s + ", 长度:" + s.length());
        }
    }
}

Iterator iterator()迭代器

集合的专用遍历方式

概述:

Iterator接口概述
对 collection 进行迭代的迭代器
依赖于集合而存在

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/*
    Iterator iterator() 迭代器,Collection集合的专用遍历方式


 */
public class CollectionDemo4 {
    public static void main(String[] args) {
        Collection c1 = new ArrayList();
        c1.add("hello");
        c1.add("world");
        c1.add("java");
        c1.add("hadoop");
        c1.add("redis");
        System.out.println("c1: " + c1);
        System.out.println("-------------------------");

        //调用方法获取迭代器对象
        Iterator iterator = c1.iterator(); //Iterator iterator = new Itr()
       
        // 遍历迭代器对象,就可以获取迭代器中的元素了
        // 我们点进Iterator观察发现,Iterator是一个接口,c1.iterator()结果一定是一个实现了Iterator接口的实现类对象
        // 要想使用迭代器对象中的方法,就去iterator()如何实现的。
        // 我们这里是借助了ArrayList子类创建的对象,去到ArrayList类中观察发现该方法返回的是一个new Itr()对象
        // 因为Itr类实现了Iterator接口,可以直接接收
        // 去Itr类中查找方法的实现,去使用并获取迭代器中的元素值
        // 我们发现Itr中有两个重要的方法:
        // hasNext()和next()
        hashNext()判断游标和集合长度是否相等,若相等,说明已经在末尾,下一个无元素。
            
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());
        while (iterator.hasNext()){
            Object o = iterator.next(); //Object o = "hello"
            String s = (String)o;
            System.out.println(s+": "+s.length());
        }




    }
}
  • 存储自定义对象并遍历 Student(name,age)

  • 1、创建集合对象

  • 2、创建元素对象

  • 3、将元素添加到集合中

  • 4、遍历集合

public class CollectionDemo5 {
    public static void main(String[] args) {
        Collection c1 = new ArrayList();

        Student s1 = new Student("张三", 18);
        Student s2 = new Student("李四", 17);
        Student s3 = new Student("王五", 18);
        Student s4 = new Student("赵六", 19);

        c1.add(s1);
        c1.add(s2);
        c1.add(s3);
        c1.add(s4);

        //方式1:转数组遍历
        Object[] array = c1.toArray();
        for (int i = 0; i < array.length; i++) {
            Object o = array[i]; // new Student("张三", 18);
            Student s = (Student) o;
            System.out.println(s.getName() + "-" + s.getAge());
        }

        System.out.println("-----------------------");
        //方式2:使用迭代器的方式遍历
        Iterator iterator = c1.iterator();
        while (iterator.hasNext()){
            Object o = iterator.next();// new Student("张三", 18);
            Student s = (Student) o;
            System.out.println(s.getName() + "-" + s.getAge());
        }


    }
}

泛型

回忆下,在此之前,我们的集合可以存放任意类型的元素,但是实际开发的时候,一个集合规定只允许放一种数据类型的元素
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());
        }


    }
}

泛型场景1:

​ 泛型类:将泛型定义在类上

<>里面的参数是为了将来调用时接收传入的引用数据类型,相当于一个形参一样,符合变量标识符命名规则就可以了
但是规范来说,泛型的名字,由一个大写的英文字母表示

 */
     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);


    }
}

泛型场景2:

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

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

    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.fun3("hello");

        demo2.fun2(12.34);
    }
}

泛型场景3:

泛型接口

把泛型定义在接口上

格式: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) {


    }
}

泛型通配符<?>

import java.util.ArrayList;
import java.util.Collection;

/*
    泛型通配符<?>
        任意类型,如果没有明确,那么就是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);
    }
}

list

Collection:
    - List: 元素有序【存储和取出的顺序一致】,允许元素发生重复,具有索引的概念
        - Set:  元素唯一且无序

public class ListDemo1 {
    public static void main(String[] args) {
        //借助ArrayList实现子类创建List接口的对象
       List list1 = new ArrayList();

        list1.add("hello");
        list1.add("world");
        list1.add("apple");
        list1.add("hadoop");
        list1.add("redis");
        list1.add("world");

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

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

    }
}

List特有方法

集合具有索引的概念,根据索引提供了List集合特有的一些功能:
void add(int index,E element)
E remove(int index)
E get(int index)
E set(int index,E element)
ListIterator listIterator()

public class ListDemo2 {
    public static void main(String[] args) {
        //借助ArrayList实现子类创建List接口的对象
        List list1 = new ArrayList();
        list1.add("hello");
        list1.add("world");
        list1.add("apple");
        list1.add("hadoop");
        list1.add("redis");
        list1.add("world"); // 集合的末尾处添加
        System.out.println("list1: " + list1);

        //[hello, world, apple, hadoop, redis, world]
        // void add(int index,Object element)
        list1.add(3,"数加");
        System.out.println("list1: " + list1);

        //[hello, world, apple, 数加, hadoop, redis, world]
        //Object remove(int index) 根据索引移除元素
//        System.out.println(list1.remove(10)); // 返回被删除的元素
//        System.out.println("list1: " + list1);

        // Object get(int index) 通过索引获取元素
//        System.out.println(list1.get(3));
//        System.out.println("list1: " + list1);
        System.out.println("======");
        System.out.println(list1.get(3));

        // Object set(int index,E element) 根据索引修改值
//        System.out.println(list1.set(3, "shujia")); //返回索引位置上的旧值
//        System.out.println("list1: " + list1);
        list1.set(1,"world");
        System.out.println(list1);
        // ListIterator listIterator() 是List集合专有的迭代器对象 要想倒着遍历,必须得先正着遍历一次
//        ListIterator listIterator = list1.listIterator();
        ListIterator listIterator = list1.listIterator();

        while (listIterator.hasNext()){
            System.out.println(listIterator.next());
        }
        System.out.println("--------------------------------------");
//        while (listIterator.hasNext()){
//            System.out.println(listIterator.next());
//        }
        while (listIterator.hasPrevious()){
            System.out.println(listIterator.previous());
        }


    }
}

list插入练习

/*
    需求:创建List集合对象,添加若干个字符串类型的元素,使用迭代器遍历,当遇到字符串
    "java"的时候,向集合中添加一个元素"shujia"。

    ConcurrentModificationException: 并发修改异常

    结论:迭代器遍历,使用迭代器修改;集合遍历,集合修改

 */
public class ListDemo3 {
    public static void main(String[] args) {
        List list1 = new ArrayList();
        list1.add("hello");
        list1.add("world");
        list1.add("java");
        list1.add("hadoop");
        list1.add("redis");
        System.out.println("list1: " + list1);
        System.out.println("-------------------------");
//        Iterator iterator = list1.iterator();
//        while (iterator.hasNext()){
//            String s = (String) iterator.next();
//            if("java".equals(s)){
//                list1.add("shujia");
//            }
//        }
//        System.out.println("list1: " + list1);
        ListIterator listIterator = list1.listIterator();
        while (listIterator.hasNext()) {
            String s = (String) listIterator.next();
            if ("java".equals(s)) {
                listIterator.add("shujia");
            }
        }
        System.out.println("list1: " + list1);

    }
}

list集合的遍历方式

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

/*
    List集合的遍历方式:
        1、先转数组再遍历
        2、获取迭代器遍历
        3、根据索引和长度使用for循环遍历【List集合专属遍历方式】
 */
public class ListDemo4 {
    public static void main(String[] args) {
        List list1 = new ArrayList();
        list1.add("hello");
        list1.add("world");
        list1.add("java");
        list1.add("hadoop");
        list1.add("redis");
        System.out.println("list1: " + list1);
        System.out.println("-------------------------");
//
        for(int i=0;i<list1.size();i++){
            Object o = list1.get(i);

            System.out.println(o);
        }

    }
}

去除集合中字符串的重复值

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);


    }
}

去除集合中自定义对象的重复值(对象的成员变量值都相同)

Student(name,age)

/*
    去除集合中自定义对象的重复值(对象的成员变量值都相同)
    Student(name,age)
 */
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);
    }
}

Linkediist

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

/*
    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);


    }
}

Linkedlist练习

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

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

package shujia.day10;

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());
        }


    }
}

Vector

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

Vector类特有功能
public void addElement(E obj)
public E elementAt(int index)
public Enumeration elements()

public class VectorDemo1 {
    public static void main(String[] args) {
        // Vector() 构造一个空向量,使其内部数据数组的大小为 10 ,标准容量增量为零。
        Vector v1 = new Vector();

        v1.add("hello");
        v1.add("world");
        v1.add("hello");
        v1.add("spark");
        v1.add("hbase");


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

        System.out.println("---------------");
        //public void addElement(Object obj) 向集合末尾添加一个元素效果和add方法一样,以后就用add方法替代
//        v1.addElement("hive");
//        System.out.println("v1: "+v1);

        //public Object elementAt(int index) 根据索引获取元素 以后也不用,使用get方法进行替代
//        System.out.println(v1.elementAt(3));
//        System.out.println(v1.get(3));

        //public Enumeration elements()  这个今后使用迭代器的方式进行替代
//        Enumeration elements = v1.elements();
//        while (elements.hasMoreElements()){
//            System.out.println(elements.nextElement());
//        }

    }
}

Collcetions工具类

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

/*
    Collections工具类
 */
public class CollectionsDemo1 {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>(); // 线程不安全的集合类对象

        List<String> list2 = Collections.synchronizedList(list1); // 线程安全的

        list2.add("hello");
        list2.add("world");
        list2.add("java");
        list2.add("hello");
        list2.add("hadoop");


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

Set

HashSet

Collection【接口】:
- List【接口】元素有序【添加和取出的顺序一致】,允许发生重复,有索引
- ArrayList: 底层数据结构是数组,查询快,增删慢,线程不安全,效率高
- Vector: 底层数据结构是数组,查询快,增删慢,线程安全,效率低,即便安全我们以后也不用
- LinkedList: 底层数据结构是双链表,增删快,查询慢,线程不安全,效率高
- Set【接口】元素无序【添加和取出的顺序不一致】,且唯一
- HashSet: 底层数据结构是哈希表,线程不安全,效率高,能够保证元素的唯一
- TreeSet

public class SetDemo1 {
    public static void main(String[] args) {
        // HashSet() 构造一个新的空集合; 背景HashMap实例具有默认初始容量(16)和负载因子(0.75)。
        HashSet<String> set1 = new HashSet<>();


        // 因为Set是Collection的子接口,HashSet是Set接口的实现类,里面必然也重写了父接口中所有的抽象方法
        set1.add("hello");
        set1.add("world");
        set1.add("hello");
        set1.add("java");
        set1.add("hello"); 
        set1.add("hadoop");
        
        
        for (String s : set1) {
            System.out.println(s);
        }

    }
}

需求:

当学生的姓名和年龄一样的时候,表示重复对象

import java.util.HashSet;

//需求:当学生的姓名和年龄一样的时候,表示重复对象
public class SetDemo2 {
    public static void main(String[] args) {
        HashSet<Student> set1 = new HashSet<>();

        Student s1 = new Student("张成阳", 18);
        Student s2 = new Student("方直", 18);
        Student s3 = new Student("张成阳", 18);
        Student s4 = new Student("黄沪生", 17);
        Student s5 = new Student("黄涛", 19);
        /*
            1、HashSet中add方法底层实际上是调用了HashMap中的put方法
            2、底层依赖于元素对象的类型中的hashCode()方法,但是我们Student类中并没有写,所以用的是Object类中的方法,
                而父亲Object类中的hashCode()是根据对象的地址值计算出一个哈希值。说明这5个对象hashCode的结果都不一样
            3、底层判断待插入的元素是否与已经在hashtable中的元素重复,是根据两个条件判断的
                1)哈希值hashCode()结果是否一样
                2)元素的equals方法结果是否一样
                我们的Student元素类中这两个方法都没有进行重写,所以任意两个Student对象的结果都不一样
                既然不一样,底层就认为不重复,不重复就添加到集合中,所以我们看到的结果是没有去重的
         */
        set1.add(s1);
        set1.add(s2);
        set1.add(s3);
        set1.add(s4);
        set1.add(s5);

        for (Student student : set1) {
            System.out.println(student);
        }

    }
}
*
    编写一个程序,获取10个1至20的随机数,要求随机数不能重复。
 */
public class SetTest1 {
    public static void main(String[] args) {

        HashSet<Integer> set1 = new HashSet<>();
        Random random = new Random();

        while (set1.size() != 10) {
            set1.add(random.nextInt(20) + 1);
        }

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



    }
}

Treeset

Collection【接口】:
- List【接口】元素有序【添加和取出的顺序一致】,允许发生重复,有索引
- ArrayList: 底层数据结构是数组,查询快,增删慢,线程不安全,效率高
- Vector: 底层数据结构是数组,查询快,增删慢,线程安全,效率低,即便安全我们以后也不用
- LinkedList: 底层数据结构是双链表,增删快,查询慢,线程不安全,效率高
- Set【接口】元素无序【添加和取出的顺序不一致】,且唯一
- HashSet: 底层数据结构是哈希表,线程不安全,效率高,能够保证元素的唯一
- LinkedHashSet: 底层数据结构是哈希表和链表,线程不安全,效率高,能够保证元素的唯一【哈希表】,有序【链表】!
- TreeSet: 底层数据结构是红黑树,具有可预测的迭代次序或自定义排序
排序方式:
1) 自然排序
2) 比较器排序

import java.util.TreeSet;

public class TreeSetDemo1 {
    public static void main(String[] args) {
        // 使用TreeSet集合存储字符串元素对象并遍历
        //TreeSet() 构造一个新的,空的树组,根据其元素的自然排序进行排序
        TreeSet<String> set1 = new TreeSet<>();
//        TreeSet<String> set = new TreeSet();
        /*
            TreeSet中的add方法底层实际上是调用了TreeMap中的put方法

         */
        set1.add("banana");
        set1.add("peach");
        set1.add("apple");
        set1.add("watermelon");
        set1.add("banana");
        set1.add("apple");
        set1.add("cherry");
        System.out.println(set1);

        for (String s : set1) {
            System.out.println(s);
        }


    }
}

需求:

使用TreeSet存储自定义对象并遍历
当教师的姓名和年龄一样的时候,认为发生重复

需求:将教师对象添加到TreeSet集合中,去重的同时,按照年龄从小到大排序

自然排序要求元素类要实现Comparable接口,并重写compareTo方法
而compareTo方法中的结果返回值,取决于需求来编写代码逻辑

public class Teacher implements Comparable<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 +
                '}';
    }

    @Override
    public int compareTo(Teacher o) {
        //按照年龄从小到大排序
        // o - 根的元素【已经存储在树中的元素】
        // this - 待插入的元素
        //显式条件:年龄从小到大排序
        //隐藏条件:年龄一样,姓名不一定一样

//        return this.getAge()-o.getAge();
        int i1 = this.getAge()-o.getAge();
        // 当年龄一样的时候,比较姓名
        return  (i1==0)?this.getName().compareTo(o.getName()):i1;

//        return -10;
    }
}
public class TreeSetDemo2 {
    public static void main(String[] args) {
        TreeSet<Teacher> set1 = new TreeSet<>();

        Teacher t1 = new Teacher("小虎", 18);
        Teacher t2 = new Teacher("杨老板", 16);
        Teacher t3 = new Teacher("笑哥", 19);
        Teacher t4 = new Teacher("旭哥", 15);
        Teacher t5 = new Teacher("小虎", 18);
        Teacher t6 = new Teacher("强哥", 18);
        set1.add(t1);
        set1.add(t2);
        set1.add(t3);
        set1.add(t4);
        set1.add(t5);
        set1.add(t6);
        for (Teacher teacher : set1) {
            System.out.println(teacher);
        }
    }
}
import java.util.Comparator;
import java.util.TreeSet;

/*
    使用比较器的方式创建TreeSet集合

    需求:书的名字和价格一样的话,重复,价格从小到大排序
 */
class MyComparator implements Comparator<Book> {
    @Override
    public int compare(Book o1, Book o2) {
        // o1 - 待插入的元素’
        // o2 - 已经在树中的元素
//        return 0;
        int i1 = o2.getPrice() - o1.getPrice();
        return (i1 == 0) ? o1.getName().compareTo(o2.getName()) : i1;
    }
}


// 按照书的名字从短到长排序
//class MyComparator2 implements Comparator<Book> {
//    @Override
//    public int compare(Book o1, Book o2) {
//        int i1 = o1.getName().length() - o2.getName().length();
//        int i2 = (i1 == 0) ? o1.getName().compareTo(o2.getName()) : i1;
//        return (i2 == 0) ? o1.getPrice() - o2.getPrice() : i2;
//    }
//}


public class TreeSetDemo3 {
    public static void main(String[] args) {
//        TreeSet<Book> books = new TreeSet<>(new MyComparator());
        TreeSet<Book> books = new TreeSet<>(new Comparator<Book>() {
            @Override
            public int compare(Book o1, Book o2) {
                int i1 = o1.getName().length() - o2.getName().length();
                int i2 = (i1 == 0) ? o1.getName().compareTo(o2.getName()) : i1;
                return (i2 == 0) ? o1.getPrice() - o2.getPrice() : i2;
           
            }
        });
        



        Book b1 = new Book("面试指南", 100);
        Book b2 = new Book("大数据spark", 98);
        Book b3 = new Book("面试指南", 100);
        Book b4 = new Book("flink开发指南", 100);
        Book b5 = new Book("java从基础到入坑", 50);

        books.add(b1);
        books.add(b2);
        books.add(b3);
        books.add(b4);
        books.add(b5);

        for (Book book : books) {
            System.out.println(book);
        }

    }
}

Map

Map【接口】:每一个元素是由键和值构成

1、在同一个Map集合中,键是唯一的,值可以发生重复
2、Map的子类HashMap,TreeMap,其中的唯一性是针对键来说的

Map接口中的方法:
V put(K key,V value)
V remove(Object key)
void clear()
boolean containsKey(Object key)
boolean containsValue(Object value)
boolean isEmpty()
int size()

public class MapDemo1 {
    public static void main(String[] args) {
        //借助Map子类HashMap来创建对象
        Map<Integer, String> map1 = new HashMap<>();

        //String put(Integer key,String value) // 返回被覆盖的旧值
        map1.put(1001, "张三");
        map1.put(1002, "李四");
        map1.put(1001, "王五");
        map1.put(1003, "赵六");

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

//        System.out.println("-----------------");
        //map1: {1001=王五, 1002=李四, 1003=赵六}
        //V remove(Object key) 根据键删除一个键值对, 返回对应的值
//        System.out.println(map1.remove(1001));
//        System.out.println("map1: " + map1);
//        System.out.println("-----------------");
//        //void clear() 清空map集合中所有的键值对元素
//        map1.clear();
//        System.out.println("map1: " + map1);
        System.out.println("-----------------");
//         boolean containsKey(Object key) 判断是否包含某个键
        System.out.println(map1.containsKey(1001));
        System.out.println("-----------------");
        // boolean containsValue(Object value) 判断是否包含某个值
        System.out.println(map1.containsValue("李四"));
        System.out.println("-----------------");
        //boolean isEmpty() 判断集合中是否有键值对
        System.out.println(map1.isEmpty());
        System.out.println("-----------------");
        // int size() 获取键值对个数
        System.out.println(map1.size());


    }
}

map遍历

V get(Object key)
Set keySet()
Collection values()
Set<Map.Entry<K,V>> entrySet()

public class MapDemo2 {
    public static void main(String[] args) {
        //借助Map子类HashMap来创建对象
        Map<Integer, String> map1 = new HashMap<>();

        //String put(Integer key,String value) // 返回被覆盖的旧值
        map1.put(1001, "张三");
        map1.put(1002, "李四");
        map1.put(1001, "王五");
        map1.put(1003, "赵六");
        map1.put(1004, "王二麻");
        map1.put(1005, "王林");

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

        System.out.println("-----------------");
        // V get(Object key) 根据键获取值
        System.out.println(map1.get(1005));
        System.out.println("map1: " + map1);
        System.out.println("-----------------");
        // Set<K> keySet() 将所有的键拿出来放到一个Set集合中
//        Set<Integer> keys = map1.keySet();
        Set<Integer> keys = map1.keySet();
        for (Integer key : keys) {
            System.out.println(key);
        }
        System.out.println("-----------------");
        // Collection<V> values() 将所有的值拿出来放到一个Collection集合中
        Collection<String> values = map1.values();
        for (String value : values) {
            System.out.println(value);
        }

        System.out.println("------------------");
        // Set<Map.Entry<K,V>> entrySet()  将每个键值对拿出来放入到Set集合中
        // map集合遍历方式1:一次获取所有的键值对,依次遍历得到每个键值对的键和值
        Set<Map.Entry<Integer, String>> entries = map1.entrySet();
        for (Map.Entry<Integer, String> entry : entries) {
            // entry -  键值对
            Integer key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + "-" + value);
        }
        System.out.println("------------------");
        // map集合遍历方式2:先获取所有的键,遍历键,根据键得到对应的值
        for (Integer key : keys) {
            // 根据键获取值
            String value = map1.get(key);
            System.out.println(key + "-" + value);
        }
        System.out.println("------------------");


    }
}

需求

"aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)

public class MapTest1 {
    public static void main(String[] args) {
        String s1 = "aababcabcdabcde";

        TreeMap<Character, Integer> map1 = new TreeMap<>();

        char[] chars = s1.toCharArray();
        for (char aChar : chars) {
            //判断集合集合是否有该键
            if(map1.containsKey(aChar)){
               map1.put(aChar, map1.get(aChar)+1);
            }else {
                map1.put(aChar, 1);
            }
        }

        StringBuilder sb = new StringBuilder();
        Set<Map.Entry<Character, Integer>> entries = map1.entrySet();
        for (Map.Entry<Character, Integer> entry : entries) {
            Character c = entry.getKey();
            Integer counts = entry.getValue();
            sb.append(c).append("(").append(counts).append(")");
        }

        String res = sb.toString();
        System.out.println(res);

    }
}

LinkedHashMap

LinkedHashMap是HashMap的子类:底层数据结构是哈希表【唯一性】和双链表【有序】

public class LinkedHashMapDemo1 {
    public static void main(String[] args) {
        LinkedHashMap<Student3, String> map1 = new LinkedHashMap<>();

        map1.put(new Student3("方直", 18), "打游戏");
        map1.put(new Student3("张成阳", 16), "看动漫");
        map1.put(new Student3("方直", 18), "看电影");
        map1.put(new Student3("黄涛", 17), "看书");
        map1.put(new Student3("康清宇", 14), "看美女");


        Set<Map.Entry<Student3, String>> entries = map1.entrySet();
        for (Map.Entry<Student3, String> entry : entries) {
            Student3 key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + "-" + value);
        }
    }
}

HashMap和Hashtable的区别

HashMap和Hashtable的区别
1、从源码上来看,HashMap有的方法,Hashtable中也有,只是单纯的使用没啥太大区别
2、HashMap的键和值都允许为null值, Hashtable的键和值都不允许为null
3、HashMap是不安全的集合类,Hashtable中的方法大部分都是被synchronized关键字修饰的,线程是安全的,效率比HashMap低一些。
public class HashtableDemo {
    public static void main(String[] args) {
        HashMap<String, String> map2 = new HashMap<>();
        map2.put(null, "hello");
        map2.put("java", null);
        map2.put(null, null);
        System.out.println("map2: " + map2);


        Hashtable<String, String> map1 = new Hashtable<>();
        map1.put(null, "hello");
        map1.put("java", null);
        map1.put(null, null);
        System.out.println("map1: " + map1);
    }
}

标签:java,list1,System,println,add,集合,public,out
From: https://www.cnblogs.com/lanzhi666/p/18677806

相关文章

  • java常用类
    java常用类Api概述API(ApplicationProgrammingInterface)应用程序编程接口编写一个机器人程序去控制机器人踢足球,程序就需要向机器人发出向前跑、向后跑、射门、抢球等各种命令,没有编过程序的人很难想象这样的程序如何编写。但是对于有经验的开发人员来说,知道机器人厂商一......
  • 算法2-1:集合union
    题目描述假设利用两个线性表LA和LB分别表示两个集合A和B(即:线性表中的数据元素即为集合中的成员),现要求一个新的集合A=A∪B。这就要求对线性表做如下操作:扩大线性表LA,将存在于线性表LB中而不存在于线性表LA中的数据元素插入到线性表LA中去。只要从线性表LB中依次取得每个元素,并......
  • Java基础学习(八)
    Java基础学习(八):字符串目录Java基础学习(八):字符串概述字符串的创建字符串内存分析String类常用方法StringBuilder类StringJoiner类字符串相关类底层原理本文为个人学习记录,内容学习自黑马程序员概述java.lang包是Java的核心包,其下的类都是无需手动导入即可使用的java.......
  • 《offer 来了:Java 面试核心知识点精讲 -- 原理篇》
    在Java面试的战场上,只知皮毛可不行,面试官们越来越看重对原理的理解。今天就给大家分享一本能让你在面试中脱颖而出的“武林秘籍”——《offer来了:Java面试核心知识点精讲--原理篇》。本书详细介绍了Java架构师在BAT和移动互联网公司面试中常被问及的核心知识,内容详细......
  • Java数组详解
    目录一、什么是数组二、声明和创建1、数组的声明2、数组的创建三、数组的初始化1.静态初始化(StaticInitialization)2.动态初始化(DynamicInitialization)3.默认初始化(DefaultInitialization)四、数组的基本使用1、访问元素2、数组长度3、遍历数组五、数组下......
  • 【华为OD-E卷 - 数组连续和 100分(python、java、c++、js、c)】
    【华为OD-E卷-数组连续和100分(python、java、c++、js、c)】题目给定一个含有N个正整数的数组,求出有多少个连续区间(包括单个正整数),它们的和大于等于x输入描述第一行两个整数Nx(0<N<=100000,0<=x<=10000000)第二行有N个正整数(每个正整数小于等于100)输出......
  • 2025高级java面试精华及复习方向总结
    1. Java基础顶顶顶顶的点点滴滴1.1java集合关系结构图 1.2 如何保证ArrayList的线程安全方法一:使用Collections工具类中的synchronizedList方法    List<String>synchronizedList=Collections.synchronizedList(newArrayList<>());使用锁机制     ......
  • 免费送源码:Java+ssm+MySQL 基于SSM的游戏论坛设计与实现 计算机毕业设计原创定制
     摘 要本论文主要论述了如何使用SSM框架开发一个游戏论坛,将严格按照软件开发流程进行各个阶段的工作,采用B/S架构JAVA技术,面向对象编程思想进行项目开发。在引言中,作者将论述游戏论坛的当前背景以及系统开发的目的,后续章节将严格按照软件开发流程,对系统进行各个阶段分析设计......
  • 免费送源码:Java+ssm+MySQL 基于ssm校园商城系统小程序 计算机毕业设计原创定制
    摘 要随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,校园商城系统小程序被用户普遍使用,为方便用户能够可以随时进行校园商城系统小程序的数据信息管理,特开发了基于ssm校园商......
  • 免费送源码:Java+ssm+MySQL Springboot大学生心理健康咨询小程序 计算机毕业设计原创定
    摘 要科技进步的飞速发展引起人们日常生活的巨大变化,电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流,人类发展的历史正进入一个新时代。在现实运用中,应用软件的工作规则和开发步骤,采用java技术建设大学......