集合的使用

数组和List

 // 二维数组的排序,先按照第一个数的降序排序,第一个数相等的情况安装第二个数的升序排序
        int[][] array2 ={
                {1,1,3},{1,5,6}
        };
        Arrays.sort(array2, (o1, o2) -> o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0]);

首先按照数组元素的第一个值进行降序排序,如果第一个值相等,则按照第二个值进行升序排序。

        for (int[] ints : array2) {
            System.out.println(Arrays.toString(ints));
        }
		// int[] --> Integer[]
        int[] arr = {1, 2, 3, 4, 5};
        Integer[] integers = Arrays.stream(arr).boxed().toArray(Integer[]::new);
		// Integer[] --> int[]
        int[] ints = Arrays.stream(integers).mapToInt(Integer::valueOf).toArray();

        for (int[] ints : array2) {
            Integer[] integers1 = Arrays.stream(ints).boxed().toArray(Integer[]::new);
            System.out.println(Arrays.deepToString(integers1));
        }

队列数组,一维数组中存储的是队列,队列中存储字符

Deque<Character>[] arrayDeques = new ArrayDeque[10];

初始化 list,并且添加新的元素

        List<Integer> list = new ArrayList<Integer>(Arrays.asList(1,2)) {{ add(0); }};
        // list 求和
        int sum = list.stream().mapToInt(i -> i).sum();

        // list 转化为数组,打印数组内容,lambda 表达式进行简化
        int[] array = list.stream().mapToInt(Integer::intValue).toArray();
        int[] lambdaArray = list.stream().mapToInt(i -> i).toArray();

        // 整形返回数组的最大值
        int arrayMax = Arrays.stream(array).max().getAsInt();

        // forEach 快速输出
        list.forEach(System.out::println);

		// 这里使用【listBug.add】可能会导致UnsupportedOperationException
        List<Integer> listBug = Arrays.asList(1, 2, 3);
        listBug.add(3);

数组静态内部的ArrayList类,长度不可变,重新构造之后,移除元素出现数组 长度动态修改

        ArrayList<String> removeList = new ArrayList<String>(Arrays.asList("a", "b", "c", "d","a","a","A"));
        for (int i = 0; i < removeList.size(); i++) {
            removeList.remove(i);
        }
        System.out.println(removeList);

结果一定是[b, d, a]

类型擦除

        ArrayList<String> list1 = new ArrayList<String>();
        list1.add("abc");
        ArrayList<Integer> list2 = new ArrayList<Integer>();
        list2.add(123);
        System.out.println(list1.getClass() == list2.getClass());

结果是true

map

// 在新建 map 时候初始化 map,需要带上后面的形参,否则爆 无法将 '<>' 用于匿名内部类
        // var map1 = new HashMap(); var 编译参数是 JDK10+ 提出
        Map<String, Integer> map = new HashMap<String, Integer>() {{
            put("a", 0);
            put("e", 1);
            put("i", 2);
            put("o", 3);
            put("u", 4);
        }};

        // 获取 map 值集合中的最大值
        Integer maxValue = map.values().stream().max(Integer::compare).get();

        // 获取 map 中 values 最大值对应的 key , values 相同的话选取较小的 key
        map.entrySet().stream().filter(e-> Objects.equals(e.getValue(),maxValue)).min(Map.Entry.comparingByKey()).get().getKey();

PriorityQueue

优先队列

public class PriorityQueueApiTest {
    public static void main(String[] args){
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new MyComparator());
        priorityQueue.offer(6);
        priorityQueue.offer(3);
        priorityQueue.offer(5);
        // new PriorityQueue<>((a,b)->b.compareTo(a)); 由大到小弹出,默认由小到大
        System.out.println("PriorityQueue 弹出元素");
        System.out.println(priorityQueue.poll());
        System.out.println(priorityQueue.poll());
        System.out.println(priorityQueue.poll());

        // 优先队列的迭代打印,首部默认最小元素其余按照链表打印
        Iterator<Integer> iterator = priorityQueue.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
    private static class MyComparator implements Comparator<Integer> {

        @Override
        public int compare(Integer o1, Integer o2) {
            int value = o1.compareTo(o2);
            if (value == 0) {
                return 0;
            }
            return value < 0 ? 1 : -1;
        }
    }
}

stream

    @Test
    public void filterStreamTest() {
        List<String> words = Arrays.stream("as as aa s".split(" ")).collect(Collectors.toList());
        System.out.println(words);
        long filterCount = words.parallelStream().filter(word -> word.length() > 3).count();
        System.out.println(filterCount);
        long distinctCount = words.parallelStream().distinct().count();
        System.out.println(distinctCount);
        List<Integer> map = words.parallelStream().map(String::toUpperCase).map(String::length).collect(Collectors.toList());
        System.out.println(map);
        boolean allMatch = words.stream().allMatch(word -> word.length() > 1);
        System.out.println(allMatch);
        words = Arrays.asList("a","aa","aaa","aaaa");
        List<String> collect = words.stream().parallel().filter(word -> word.length() < 2).collect(Collectors.toList());
        System.out.println(collect);
        Optional<String> any = words.stream().parallel().filter(word -> word.length() < 2).findAny();
        System.out.println(any.orElse("no"));
    }

结果依次是

[as, as, aa, s]
0
3
[2, 2, 2, 1]
false
[a]
a

Arrays.stream("as as aa s".split(" ")).collect(Collectors.toList()) 字符串分割后的数组转为集合

words.parallelStream().filter(word -> word.length() > 3).count() 集合并行流过滤出字符串长度大于3的数目

words.parallelStream().distinct().count() 集合并行流去重后集合的数量

words.parallelStream().map(String::toUpperCase).map(String::length).collect(Collectors.toList()) 集合并行流处理后将字符串映射全大写的,在映射为字符串的长度,收集为集合返回

words.stream().allMatch(word -> word.length() > 1) 集合转化为流匹配每一个字符串是否存在长度大于1

words.stream().parallel().filter(word -> word.length() < 2).collect(Collectors.toList()) 集合转为流,并行过滤出集合元素长度小于2的收集为集合

words.stream().parallel().filter(word -> word.length() < 2).findAny() 集合转为流并行处理过滤长度小于2的能否找到一个,找到的话any.orElse("no")或者any.get()输出找到的数据,没有就输出no

函数型接口

供给型接口 接受一个输入参数T,返回一个结果R。

    @Test
    public void applyApi0416(){
        Function<String, String> apply = new Function<String, String>() {
            @Override
            public String apply(String s) {
                return s;
            }
        };
        System.out.println(apply.apply("apply function interface"));

        // lambda 表达式简化
        Function<String,String> lambdaApply = ((s -> {return s;}));
        System.out.println(lambdaApply.apply("lambdaApply"));

    }

消费型接口函数 接受一个输入参数并且无返回值。没有出参,常用于打印、发送短信等消费动作

    @Test
    public void consumerApi0416(){
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s.concat("--->accept"));
            }
        };
        consumer.accept("hello");

        // lambda 表达式简化
        Consumer<String> lambdaConsumer = (String s)->{
            System.out.println(s.concat("--->lambdaConsumer"));
        };
        lambdaConsumer.accept("world");
    }

断言式函数接口:接受一个输入参数T,返回一个布尔值结果。常用于条件判断

    @Test
    public void predicateApi0416(){
        Predicate<String> predicate = new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.isEmpty();
            }

            @Override
            public Predicate<String> negate() {
                return Predicate.super.negate();
            }

            @Override
            public Predicate<String> or(Predicate<? super String> other) {
                return Predicate.super.or(other);
            }
        };
        System.out.println(predicate.test(""));
        System.out.println(predicate.negate());

        // lambda 简化
        Predicate<String> lambdaPredicate = ((str) -> {
            return !str.isEmpty();
        });
        System.out.println(lambdaPredicate.test(""));
    }

供需型接口函数 无输入参数,返回一个结果T。常用于符合条件时调用获取结果;运行结果提前定义,但不运行。

    @Test
    public void supplierApi0416(){
        Supplier<String> supplier = new Supplier<String>() {
            @Override
            public String get() {
                return "get()";
            }
        };
        System.out.println(supplier.get());

        // lambda 表达式简化
        Supplier<Integer> lambdaSupplier = ()->{return 1024;};
        System.out.println(lambdaSupplier.get());
    }

线程

线程的创建和启动

public class ThreadCreateApiTest {

    private volatile int tickets = 50;

    @Test
    public void threadCreate0416() throws ExecutionException, InterruptedException {
        MyThread1 myThread1 = new MyThread1();
        MyThread2 myThread2 = new MyThread2();
        Mythread3 mythread3 = new Mythread3();

        new Thread(myThread1,"thread").start();

        new Thread(myThread2,"runnable").start();

        FutureTask<String> futureTask = new FutureTask<>(mythread3);
        new Thread(futureTask,"callable1").start();
        new Thread(futureTask,"callable2").start();

        System.out.println(futureTask.get());
    }

    /**
     * 创建线程方法一
     * 继承 Thread 类
     * 重写 run() 包含了业务,多线程考虑酌情加锁
     * 创建对象,对象调用 start() 开启线程
     */
    class MyThread1 extends Thread{
        @Override
        public synchronized void run() {
            // Thread.currentThread().getName() 获取当前线程的名字
            while (true){
                if (tickets <= 0) {
                    break;
                }
                System.out.println(Thread.currentThread().getName()+"拿到了第"+ tickets -- +"张票");
            }
        }
    }

    /**
     * 创建线程方法二
     * 实现 Runnable 接口
     * 重写 run() 包含了业务,多线程考虑酌情加锁
     * 创建对象,对象作为 Thread 构造参数产生的对象去调用 start() 开启线程
     */
    class MyThread2 implements Runnable{
        @Override
        public synchronized void run() {
            while (true){
                if (tickets <= 0) {
                    break;
                }
                System.out.println(Thread.currentThread().getName()+"拿到了第"+ tickets -- +"张票");
            }
        }
    }

    /**
     * 创建线程方法三
     * 实现 Callable 接口,形参是 call 的返回值类型
     * 重写 call() 包含了业务,多线程考虑酌情加锁,返回值可通过 FutureTask 的 get() 获取
     * 创建对象,对象作为 FutureTask 的构造参数传入 产生的 FutureTask 对象
     * 这个 FutureTask 对象作为 Thread 的构造参数传入产生的对象调用 start() 开启线程
     */
    class Mythread3 implements Callable<String>{
        @Override
        public synchronized String call() throws Exception {
            while (true){
                if (tickets <= 0) {
                    break;
                }
                System.out.println(Thread.currentThread().getName()+"拿到了第"+ tickets -- +"张票");
            }
            return "Mythread3 mplements Callable 的 return";
        }
    }
}

线程安全的加锁

public class ThreadSaleTicketTest {
    @Test
    public void testSynchronizedSaleTicket() {
        TicketWindow ticketWindow = new TicketWindow();

        // 旧方式创建线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 30; i++) {
                    ticketWindow.synchronizedSaleTicket();
                }
            }
        },"Window A").start();

        // 新方式创建线程
        new Thread(()->{
            for (int i = 0; i < 30; i++) {
                ticketWindow.synchronizedSaleTicket();
            }
        },"Window B").start();

        new Thread(()->{
            for (int i = 0; i < 40; i++) {
                ticketWindow.synchronizedSaleTicket();
            }
        },"Window C").start();
    }

    @Test
    public void testLockSaleTicket(){
        TicketWindow ticketWindow = new TicketWindow();
        new Thread(() -> {
            for (int i = 0; i < 30; i++) {
                ticketWindow.lockSaleTicket();
            }
        }, "Window A").start();

        new Thread(() -> {
            for (int i = 0; i < 30; i++) {
                ticketWindow.lockSaleTicket();
            }
        },"Window B").start();

        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                ticketWindow.lockSaleTicket();
            }
        },"Window C").start();
    }

}

/**
 * tickets:电影票,volatile 可见性,禁止指令重排序
 * synchronizedSaleTicket():synchronized 关键字实现安全的买票
 * lockSaleTicket():lock 实现类实现安全的买票
 */
class TicketWindow {
    private volatile int tickets = 100;
    private final Lock lock = new ReentrantLock(true);

    public void synchronizedSaleTicket() {
        while (tickets > 0) {
            synchronized (TicketWindow.class) {
                System.out.println(Thread.currentThread().getName() + "卖出了第 " + tickets-- + " 张票,剩余了 " + tickets + " 张票");
            }
        }
    }

    /**
     * 存在问题:窗口有票,但是票没有卖完,原因窗口过度的买票,虚假信息穿透 if,将判断条件改为 while 即可解决
     */
    public void lockSaleTicket() {
        lock.lock();
        try {
            while (tickets > 0) {
                System.out.println(Thread.currentThread().getName() + "卖出了第 " + tickets-- + " 张票,剩余了 " + tickets + " 张票");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
    }
}

你可能感兴趣的:(java基础,开发语言)