10. Java核心API

Java —— String字符串

          • 1. Java集合Collection
          • 2. 共用方法(Collection常见API)
          • 3. 泛型
          • 4. List集合和排序
            • 4.0 List排序
          • 5. Lambda表达式

1. Java集合Collection
集合Collection:Java集合是一组用于存储和操作数据的类和接口(集合是一种可以存放多个数据的容器)
Java集合主要接口和实现类
    ▶ List(列表):提供有序、可重复的元素集合
      ⯈ ArrayList(动态数组):基于动态数组的数据结构 —— 插入和删除效率低,元素访问效率高(非线程安全)
         特性:① 有序 元素按照插入的顺序进行存储,通过索引访问和修改元素
             ② 可重复 ArrayList允许存储重复的元素
             ③ 动态扩容 元素数量超过当前容量时,会自动进行扩容以容纳更多的元素
             ④ 随机访问 ArrayList内部使用数组实现,可以通过索引快速访问元素,时间复杂度为O(1)
             ⑤ 插入和删除效率较低 在ArrayList的中间位置插入或删除元素会导致后续元素的移动,时间复杂度为O(n)
      ⯈ LinkedList(链表):一个双向链表实现类,实现了List和Deque接口 —— 插入和删除效率高,元素访问效率低(非线程安全)
         特性:① 有序 元素按照插入的顺序进行存储,通过索引访问和修改元素
             ② 可重复 LinkedList允许存储重复的元素
             ③ 链表结构 LinkedList内部使用链表数据结构来存储元素,每个元素都包含一个指向前一个元素和后一个元素的引用
             ④ 动态添加和删除 由于LinkedList使用链表实现,插入和删除元素的效率较高,时间复杂度为O(1)
             ⑤ 随机访问效率较低 LinkedList不支持通过索引直接访问元素,效率较低,需要遍历链表来查找指定位置的元素,时间复杂度为O(n)
    ▶ Set(集):提供无序、不可重复的元素集合
      ⯈ HashSet(基于哈希表): —— 插入和删除效率高,元素访问效率低(非线程安全)
         特性:① 哈希表 HashSet内部使用哈希表数据结构来存储元素,通过计算元素的哈希值来确定其在哈希表中的位置
             ② 无序性 HashSet中的元素是无序的,即元素之间没有固定的顺序
             ③ 唯一性 HashSet中不能包含重复的元素,确保了集合中元素的唯一性
             ④ 高效性 HashSet使用哈希表来存储元素,所以对于插入、删除和查找操作,平均时间复杂度为O(1)
             ⑤ 不支持索引 HashSet中的元素是无序的,所以无法通过索引来直接访问元素
      ⯈ TreeSet(基于红黑树):一个集合类,实现了SortedSet接口并继承了AbstractSet类
         特性:① 红黑树 TreeSet内部使用红黑树(Red-Black Tree)数据结构来存储元素,所以它具有自动排序的特性
             ② 有序性 TreeSet中的元素按照排序顺序进行存储,默认是按照元素的自然顺序进行排序,或者可以通过传递一个自定义的比较器(Comparator)来指定排序规则
             ③ 唯一性 TreeSet中不能包含重复的元素,确保了集合中元素的唯一性
             ④ 高效性 TreeSet使用红黑树来存储元素,所以对于插入、删除和查找操作,平均时间复杂度为O(log n)
             ⑤ 支持导航方法 TreeSet提供了一些导航方法,如first()、last()、lower()、higher()等,可以方便地获取集合中的最小元素、最大元素,以及比给定元素小或大的元素
    ▶ Queue(队列):提供一种先进先出(FIFO)的数据结构
      ⯈ ArrayDeque(动态数组,包含LinkedList):都实现了Deque接口,可以用于实现队列(Queue)和双端队列(Deque)的操作
         特性:① 自动扩容 ArrayDeque使用循环数组来存储元素,当数组元素不足时会自动扩容
             ② 高效性 ArrayDeque对插入和删除操作具有较好的性能,时间复杂度为O(1),但在需要自动扩容时,插入和删除操作会带来较高的开销
             ③ 随机访问 ArrayDeque支持通过索引直接访问元素,时间复杂度为O(1),但并不适合大量随机访问操作

Map(映射):提供一种键值对的映射关系
      ⯈ HashMap(基于哈希表):一个集合类,实现了Map接口,用于存储键值对数据
         特性:① 键值对存 HashMap以键值对的形式存储数据,每个键与唯一的值相关联
             ② 高效性能 HashMap提供了常数时间复杂度(O(1))的插入、删除和查找操作,对于大多数情况下的操作都能够保持高效
             ③ 无序性 HashMap中的元素没有固定的顺序,不会以插入的顺序或者键的自然顺序进行排序
             ④ 允许null键和null值 HashMap允许键和值都为null,但只能有一个null键
             ⑤ 键的唯一性 HashMap要求键的唯一性,即同一个HashMap对象中不能同时存在相同的键
      ⯈ TreeMap(基于红黑树):一个集合类,实现了SortedMap接口
         特性:① 排序 TreeMap中的键值对按照键的顺序进行排序(如果键是基本类型或String类型,则按照自然顺序排序。如果键是自定义类型,则需要实现Comparable接口或提供Comparator来定义比较规则)
             ② 唯一键 TreeMap中的键是唯一的,不允许重复(如果插入具有相同键的元素,则新元素将替换旧元素)
             ③ 搜索和检索 TreeMap支持高效的搜索和检索操作(如果键是基本类型或String类型,则按照自然顺序排序。如果键是自定义类型,则需要实现Comparable接口或提供Comparator来定义比较规则)
             ④ 遍历 TreeMap提供了多种遍历方式,包括按键升序、降序等方式遍历(通过keySet()方法获取键的集合,然后进行遍历。也可以使用entrySet()方法获取键值对的集合,然后进行遍历)
             ⑤ 子映射 TreeMap支持子映射操作,可以根据键的范围获取子映射

注意点:
  HashSet
    ① 添加元素时,HashSet会根据元素的hashCode()方法返回的哈希值来确定元素在哈希表中的存储位置
    ② 为了保证元素的唯一性,HashSet会调用元素的equals()方法来判断两个元素是否相等
    ③ 在使用自定义对象作为HashSet的元素时,需要正确重写hashCode()和equals()方法,以确保元素的唯一性
  TreeSet
    ① 添加元素时,TreeSet会根据元素的比较结果来确定元素在红黑树中的存储位置
    ② 为了保证元素的唯一性和排序准确性,TreeSet要求元素必须实现Comparable接口或者在创建TreeSet时传递自定义的比较器
    ③ 在使用自定义对象作为TreeSet的元素时,需要正确实现Comparable接口的compareTo()方法或者构造自定义的Comparator来定义排序规则

  • 为了便于使用和维护,JDK类库按照包结构划分,不同功能的类划分在不同的包中(集合是一种可以存放多个数据的容器)
2. 共用方法(Collection常见API)
  1. 添加元素
        ➤ boolean add(E element): 将指定元素添加到集合中,并返回添加是否成功
        ➤ boolean addAll(Collection collection): 将指定集合中的所有元素添加到当前集合中,并返回添加是否成功
  2. 删除元素
        ➤ boolean remove(Object element): 从集合中删除指定元素,并返回删除成功与否
        ➤ boolean removeAll(Collection collection): 从集合中删除包含在指定集合中的所有元素,并返回删除成功与否
        ➤ void clear(): 清空集合中的所有元素
  3. 判断集合是否包含元素
        ➤ boolean contains(Object element): 判断集合是否包含指定元素
        ➤ boolean containsAll(Collection collection): 判断集合是否包含指定集合中的所有元素
  4. 获取集合的大小和判断是否为空
        ➤int size(): 返回集合中元素的数量
        ➤boolean isEmpty(): 判断集合是否为空
  5. 遍历集合:
        ➤ Iterator iterator(): 返回一个迭代器用于遍历集合中的元素。
        ➤ forEach(Consumer action): 对集合中的每个元素执行指定的操作。
  6. 转换成数组
        ➤ Object[] toArray(): 将集合转换为一个数组
        ➤ T[] toArray(T[] array): 将集合转换为指定类型的数组
  7. 比较和排序
        ➤ boolean equals(Object object): 判断集合是否与指定对象相等
        ➤ int hashCode(): 返回集合的哈希码值
        ➤ void sort(Comparator comparator): 对集合中的元素进行排序
  • 集合创建及部分方法演示
package collections.list;

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


/**
 * 利用接口创建集合
 */
public class ArrayListDemo {
    public static void main(String[] args) {
        Collection arrayList = new ArrayList();
        // add添加元素,返回布尔值
        arrayList.add("集合");
        arrayList.add("List");
        arrayList.add("List");
        arrayList.add("set");
        System.out.println("集合ArrayList(有序):" + arrayList);
        System.out.println("集合元素个数:" + arrayList.size());
        System.out.println("集合是否为空:" + arrayList.isEmpty());
        // 清空集合元素
        arrayList.clear();
        System.out.println("清空后的集合:" + arrayList);


        // set
        Collection set = new HashSet();
        set.add("集合");
        set.add("List");
        set.add("List");
        set.add("set");
        System.out.println("集合set(无序,无重复):" + set);


        // 利用自定义类测试
        Collection points = new ArrayList();
        points.add(new Point(1, 2));
        points.add(new Point(1, 2));
        points.add(new Point(1, 8));
        points.add(new Point(5, 8));

        System.out.println("集合的元素:" + points);

        // contains方法(底层使用的是equals方法,需要在Point类中重写equals方法)
        boolean contains = points.contains(new Point(1, 2));
        System.out.println("是否包含元素:" + contains);
        // remove删除(只删除匹配到的第一个元素)
        Point a = new Point(1, 2);
        points.remove(a);
        System.out.println("删除后的集合:" + points);


        //
        Collection hashSet = new HashSet();
        Collection system = new HashSet();
        hashSet.add("java");
        hashSet.add("python");
        hashSet.add("C++");
        hashSet.add("android");
        hashSet.add("ios");
        System.out.println("hashset集合:" + hashSet);
        // system集合
        system.add("android");
        system.add("ios");
        System.out.println("system集合:" + system);
        boolean containsAll  = hashSet.containsAll(system);
        System.out.println("hashset集合是否全部包含system集合:" + containsAll);

        // 取交集retainAll(只影响hashset)
        hashSet.retainAll(system);
        System.out.println("(交集)hashset集合:" + hashSet);
        System.out.println("(交集)system集合:" + system);

        // 集合存放引用数据类型
        Point p = new Point(1, 2);
        Collection ps = new ArrayList();
        ps.add(p);
        System.out.println("修改之前:" + ps);
        p.setX(5);
        p.setY(6);
        System.out.println("修改之后:" + ps);
    }
}
  • Point类
package collections.list;

import java.util.Objects;

public class Point {
    private int x;
    private int y;

    public Point() {
    }

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    @Override
    public String toString() {
        return "(" + x + ", " + y + ")";
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Point point = (Point) o;
        return x == point.x && y == point.y;
    }

    @Override
    public int hashCode() {
        return Objects.hash(x, y);
    }
}
3. 泛型
泛型:Java中编写类型安全且可重用代码的一种机制
作用:在编写代码时使用指定类型,而不是在运行时强制转换类型
  泛型是Java SE5.0引入的特性,泛型的本质是参数化类型
  类、接口和方法的定义过程中,所操作的数据类型由被传入的参数所指定
  往集合中存放基本数据类型时,(继承于object)会触发自动装箱操作
  Java泛型机制广泛的应用在集合框架中,所有的集合类型都带有泛型参数(创建集合时可以指定放入集合中元素的类型)

▶ 注:
   集合中存储的都是引用类型元素,且值保存每个元素对象的引用,而不是将元素对象本身存入集合
往集合中存放基本数据类型时,(继承于object)会触发自动装箱操作
   当用一个输入的字符串和已知字符串做比较时,通常使用已知字符.equals(输入字符) —— 输入空字符时不会报错,程序继续执行;输入字符.equals(已知字符) —— 输入空字符而使程序报错
   增强for循环
for(数据类型 变量名: 集合/数组){ 操作 }

package collections.list;


import java.util.*;

/**
 * 泛型: JDK5之后提出的新特性
 */
public class Genericity {
    public static void main(String[] args) {
        // 泛型初步使用
        Collection<String> list = new ArrayList<>();
        list.add("one");
        list.add("#");
        list.add("tow");
        list.add("#");
        list.add("three");
        list.add("#");
        list.add("four");
        list.add("#");
        list.add("five");
        System.out.println("String集合:" + list);


        /*
         * 集合的遍历 集合提供了统一的遍历方式:迭代器模式
         * Iterator iterator(),使用时也要指定泛型
         */
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String elment = it.next();
            if ("#".equals(elment)){
                // 删除#
                it.remove();
            }
        }
        System.out.println("删除之后的集合:" + list);


        /*
         * 存入整数,遍历
         */
        Collection<Integer> integer = new ArrayList<>();
        for (int i = 1; i <= 100; i++) {
            integer.add(i);
        }
        System.out.println("整型集合:" + integer);
        Iterator<Integer> iterator = integer.iterator();
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }

        /*
         * 增强for循环
         */
        for (String e : list) {
            System.out.println("增强for循环:" + e);
        }

        LinkedList linkedList = new LinkedList<>();
        linkedList.add("java");
        linkedList.add("python");
        linkedList.add("c++");
        System.out.println("获取第三个元素:" + linkedList.get(2));

        for (int i = 0; i < linkedList.size(); i++) {
            System.out.println(linkedList.get(i));
        }
//        String old = String.valueOf(linkedList.set(2, "C#"));
        var old = linkedList.set(2, "C#");
        System.out.println("替换后的集合:" + linkedList);
        System.out.println("被替换的元素:" + old);

        var olds = linkedList.remove(2);
        System.out.println("删除后的集合:" + linkedList);
        System.out.println("被删除的元素:" + olds);


        // 集合的截取
        List<Integer> list1 = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list1.add(i);
        }
        List<Integer> subLists = list1.subList(3, 8);
        System.out.println("子集:" + subLists);

        for (int i = 0; i < list1.size(); i++) {
            list1.set(i, list1.get(i) * 10);
        }
        System.out.println("元素×10之后的集合:" + list1);
        // 删除(利用子集:对子集的操作就是对原集合的操作)/clear()
        list1.removeAll(list1.subList(3, 8));
        System.out.println("删除后的集合:" + list1);
    }
}
4. List集合和排序
List接口:Collection的子接口,用于定义线性表数据结构(相当于存放对象的数组,元素个数可以动态增减)
List的实现类:ArrayList(动态数组)和LinkedList(链表),二者逻辑一样,性能不同

数组与集合之间的转换
    集合转数组:集合名.toArray(new 数组类型[数组长度]);

package connection.list;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CollectionToArray {
    public static void main(String[] args) {
        List<String> strings = new ArrayList<>();
        strings.add("one");
        strings.add("tow");
        strings.add("three");
        strings.add("four");
        strings.add("five");

        // 集合转为数组
        String[] array = strings.toArray(new String[strings.size()]);
        System.out.println("数组:" + Arrays.toString(array));
    }
}

    数组转集合:Arrays.asList(数组);
直接由数组转化而来的集合,因为数组定长的特性(长度不变),对应的也无法给集合添加新元素;需要修改时,需要重新创建集合(将由数组转化的集合作为新创建数组的参数)
  即返回的集合我们不能对其增删元素,否则会抛出异常
  对集合的元素进行修改会影响数组对应的元素

package connection.list;


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

/**
 * 数组转为List
 * @author LongYongchuan
 */
public class AsList {
    public static void main(String[] args) {
        String[] strings = {"one", "tow", "three", "four", "five"};
        System.out.println("数组:" + Arrays.toString(strings));

        // 转化
        List<String> list = Arrays.asList(strings);
        System.out.println("List集合:" + list);

        // 对集合元素的操作就是对数组的操作
        list.set(1, "二");
        System.out.println("修改元素后的集合:" + list);
        System.out.println("也作用于数组:" + Arrays.toString(strings));
        // 根据数组定长的特性(长度不变),对应的也无法给集合添加新元素
        // list.add("5");             // ----- 不支持操作异常

        // 需要修改时,需要重新创建集合(将由数组转化的集合作为新创建数组的参数)
        List<String> lists = new ArrayList<>(list);
        System.out.println("新创建的集合:" + lists);
        // 添加元素
        lists.add("七");
        System.out.println("添加之后的集合:" + lists);
    }
}
4.0 List排序
Collections类的sort()方法:对List集合进行原地排序(即在原集合上进行排序)
Stream API的sorted()方法:sorted()方法返回一个新的排序后的流,不会修改原始集合
    Collections.sort()方法可以直接对List集合进行排序
    Collections.sort()方法结合自定义的Comparator(匿名内部类)来对对象进行排序
      字符串的排序是按照Unicode编码进行排序的(对中文的排序无意义)
  • 一般整型数据字符排序
package connection.list;

import java.util.*;

/**
 * 对集合进行排序
 * @author LongYongchuan
 */
public class SortList {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            list.add(random.nextInt(100));
        }
        System.out.println("原集合:" + list);
        // 对集合进行排序
        Collections.sort(list);
        System.out.println("排序后的集合:" + list);
    }
}
  • 字符串排序:根据Unicode编码进行排序
package connection.list;

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

public class StringSort {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Tom");
        list.add("tab");
        list.add("jack");
        list.add("Bob");
        list.add("rose");
        list.add("ada");
        list.add("Alen");
        list.add("bill");
        System.out.println("集合:" + list);
        // 排序(按照ASCII码排序,对中文排序没有意义)
        Collections.sort(list);
        System.out.println("排序后的集合:" + list);
    }
}
5. Lambda表达式
lambda表达式:Java 8引入的一种函数式编程的特性,它提供了一种简洁、灵活的方式来表示匿名函数

    ▶ 格式:(parameter_list) -> { lambda_body }
      ⯈ 参数列表(parameter_list):指定了Lambda表达式所使用的参数,可以为空或包含一个或多个参数
      ⯈ 箭头符号(->):将参数列表与Lambda体分隔开
      ⯈ Lambda体(lambda_body):指定了Lambda表达式的执行逻辑,可以是一个表达式或代码块
         形式:① 无参数的Lambda表达式() -> { System.out.println("Hello, World!"); }
             ② 单个参数的Lambda表达式(x) -> { System.out.println(x); } 简写: x -> System.out.println(x);
             ③ 多个参数的Lambda表达式(x, y) -> { System.out.println(x + y); }

当要实现的接口有且只有一个抽象方法时,可以利用lambda表达式简写
参数类型可以不写,方法体可以不写(方法体只有一句代码),同时必须忽略return关键字
通常格式: (参数列表) ->{
        方法体
      }

方法引用
静态方法引用:ClassName::staticMethodName
     例:Math::max(引用Math类中的静态方法max)
实例方法引用:objectReference::instanceMethodName
     例:String::length(引用字符串对象的length方法)
对象方法引用:ClassName::instanceMethodName
     例:ArrayList::size(引用ArrayList类实例的size方法)
构造方法引用:ClassName::new
     例:ArrayList::new(引用ArrayList类的构造方法)

方法引用可以简化代码,并提高可读性;通常与函数式接口(Functional Interface)一起使用,用于传递方法或构造方法作为参数

package lambda;


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

/**
 * Lambda表达式
 * lambda表达式可以用更简洁的语法创建匿名内部类lambda表达式又称为“箭头函数",
 * 主要目的是省去了匿名内部类创建时接口与方法的编写,可以更突出重写方法的逻辑部分。
 * 只有当实现的接口中包含唯一一个抽象方法时才可以使用Lambda表达式
 * 语法:
 * (参数列表)->{
 * 方法体
 * }
 * @author LongYongchuan
 */
public class LambdaDemo {
    public static void main(String[] args) {
        List<String> name = new ArrayList<>();
        name.add("戚娜娜");
        name.add("毛文");
        name.add("郝楠楠");
        name.add("欧阳云宇");
        name.add("董瑞");

        Collections.sort(name, comparators);
        System.out.println("按照名字长度排序:" + name);
    }

    // lambda表达式
    static Comparator<String> comparator = (String o1, String o2) -> {
        return o1.length() - o2.length();
    };

    // lambda表达式中的方法参数类型可以不写(方法体只有一行代码时,return及{}可以不写)
    static Comparator<String> comparator1 = (o1,o2) -> o1.length() - o2.length();

    // 精简写法
    static Comparator<String> comparators = Comparator.comparingInt(String::length);
}
package lambda;

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

public class LambdaTraverse {
    public static void main(String[] args) {
        Collection<String> num = new ArrayList<>();
        num.add("one");
        num.add("tow");
        num.add("three");
        num.add("four");
        num.add("five");

        System.out.println("集合:" + num);

        // lambda表达式
        num.forEach(o -> System.out.println(o));
        // 精简(方法引用)
        num.forEach(System.out::println);
    }
}

你可能感兴趣的:(java网络编程,java,哈希算法,开发语言)