集合根接口
所有的集合类最终都是实现自集合根接口的,比如ArrayList类,它的祖先就是Collection接口
LIST列表
import java.util.ArrayList; //集合类基本都是在java.util包下定义的 public class Main { public static void main(String[] args) { //List<String> list = new ArrayList<>(); ArrayList<String> list = new ArrayList<>(); list.add("中文"); list.add(0,"coleak"); list.add("9"); list.add("cc"); list.add("ay"); list.sort(String::compareTo); System.out.println(list); System.out.println(list.contains("coleak")); System.out.println(list.get(2)); System.out.println(list.remove("colea")); System.out.println(list.remove("coleak")); System.out.println(list.remove(1)); System.out.println(list); System.out.println(list.indexOf("中文")); } }
[9, ay, cc, coleak, 中文]
true
cc
false
true
ay
[9, cc, 中文]
2
import java.util.ArrayList; import java.util.Arrays; public class Main { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(Arrays.asList("aaa","bb","c")); list.add("aaa"); list.add("aab"); list.add("aaaa"); list.removeIf(s ->s.length()!=3); System.out.println(list); } }
[aaa, aaa, aab]
迭代器
import java.util.Arrays; import java.util.Iterator; import java.util.List; public class Main { public static void main(String[] args) { List<String> list = Arrays.asList("A", "B", "C"); Iterator<String> var = list.iterator(); while(var.hasNext()) { String s = (String)var.next(); System.out.println(s); } } }
迭代器的使用是一次性的,用了之后就不能用了,如果需要再次进行遍历操作,那么需要重新生成一个迭代器对象
import java.util.Arrays; import java.util.Iterator; import java.util.List; public class Main { public static void main(String[] args) { List<String> list = Arrays.asList("A", "B", "C"); list.forEach(System.out::println); } }
import java.util.Arrays; import java.util.Iterator; import java.util.List; public class Main { public static void main(String[] args) { Test test=new Test(); test.forEach(System.out::println); } public static class Test implements Iterable<String>{ //这里我们随便写一个类,让其实现Iterable接口 @Override public Iterator<String> iterator() { return new Iterator<String>() { //生成一个匿名的Iterator对象 @Override public boolean hasNext() { //这里随便写的,直接返回true,这将会导致无限循环 return true; } @Override public String next() { //每次就直接返回一个字符串吧 return "coleak"; } }; } } }
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.ListIterator; public class Main { public static void main(String[] args) { List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C")); ListIterator<String> iterator = list.listIterator(); iterator.next(); //此时得到A iterator.set("X"); //将A原本位置的上的元素设定为成新的 System.out.println(list); iterator.remove(); iterator.forEachRemaining(System.out::println); } }
[X, B, C]
B
C
Queue|Deque|PriorityQueue
public interface Queue<E> extends Collection<E> { //队列的添加操作,是在队尾进行插入(只不过List也是一样的,默认都是尾插) //如果插入失败,会直接抛出异常 boolean add(E e); //同样是添加操作,但是插入失败不会抛出异常 boolean offer(E e); //移除队首元素,但是如果队列已经为空,那么会抛出异常 E remove(); //同样是移除队首元素,但是如果队列为空,会返回null E poll(); //仅获取队首元素,不进行出队操作,但是如果队列已经为空,那么会抛出异常 E element(); //同样是仅获取队首元素,但是如果队列为空,会返回null E peek(); } import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); //当做队列使用,还是很方便的 queue.offer("AAA"); queue.offer("BBB"); System.out.println(queue.poll()); System.out.println(queue.poll()); } }
可以直接将一个LinkedList当做一个队列来使用
//在双端队列中,所有的操作都有分别对应队首和队尾的 public interface Deque<E> extends Queue<E> { //在队首进行插入操作 void addFirst(E e); //在队尾进行插入操作 void addLast(E e); //不用多说了吧? boolean offerFirst(E e); boolean offerLast(E e); //在队首进行移除操作 E removeFirst(); //在队尾进行移除操作 E removeLast(); //不用多说了吧? E pollFirst(); E pollLast(); //获取队首元素 E getFirst(); //获取队尾元素 E getLast(); //不用多说了吧? E peekFirst(); E peekLast(); //从队列中删除第一个出现的指定元素 boolean removeFirstOccurrence(Object o); //从队列中删除最后一个出现的指定元素 boolean removeLastOccurrence(Object o); // *** 队列中继承下来的方法操作是一样的,这里就不列出了 *** ... // *** 栈相关操作已经帮助我们定义好了 *** //将元素推向栈顶 void push(E e); //将元素从栈顶出栈 E pop(); // *** 集合类中继承的方法这里也不多种介绍了 *** ... //生成反向迭代器,这个迭代器也是单向的,但是是next方法是从后往前进行遍历的 Iterator<E> descendingIterator(); } import java.util.Deque; import java.util.LinkedList; public class Main { public static void main(String[] args) { Deque<String> deque = new LinkedList<>(); deque.push("AAA"); deque.push("BBB"); System.out.println(deque.pop()); System.out.println(deque.pop()); } }
import java.util.PriorityQueue; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<Integer> queue = new PriorityQueue<>(); queue.offer(10); queue.offer(4); queue.offer(5); System.out.println(queue.poll()); System.out.println(queue.poll()); System.out.println(queue.poll()); } } import java.util.PriorityQueue; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<Integer> queue = new PriorityQueue<>((a,b)->b-a); queue.offer(10); queue.offer(4); queue.offer(5); System.out.println(queue.poll()); System.out.println(queue.poll()); System.out.println(queue.poll()); } }
4
5
10
10
5
4
Set集合
- 不允许出现重复元素
- 不支持随机访问(不允许通过下标访问)
HashSet
import java.util.Arrays; import java.util.HashSet; import java.util.Set; public class Main { public static void main(String[] args) { Set<String> set = new HashSet<>(); System.out.println(set.add("AAA")); //这里我们连续插入两个同样的字符串 System.out.println(set.add("AAA")); System.out.println(set); //可以看到,最后实际上只有一个成功插入了 System.out.println(set.remove("AAA")); System.out.println(set); set.addAll(Arrays.asList("A", "0", "-", "+")); System.out.println(set); } }
true
false
[AAA]
true
[]
[0, A, +, -]
LinkedHashSet
维持插入集合的顺序需要使用LinkedHashSet
public static void main(String[] args) { Set<String> set = new LinkedHashSet<>(); set.addAll(Arrays.asList("A", "0", "-", "+")); System.out.println(set); }
[A, 0, -, +]
TreeSet
它会在元素插入时进行排序
import java.util.TreeSet; public class Main { public static void main(String[] args) { TreeSet<Integer> set = new TreeSet<>((a,b)->b-a); set.add(1); set.add(3); set.add(2); System.out.println(set); } }
[3, 2, 1]
键盘读入
import java.util.Scanner; public class test { public static void main(String[] args) { //演示接受用户的输入 //步骤 //Scanner类 表示 简单文本扫描器,在java.util 包 //1. 引入/导入 Scanner类所在的包 //2. 创建 Scanner 对象 , new 创建一个对象,体会 // myScanner 就是 Scanner类的对象 Scanner myScanner = new Scanner(System.in); //3. 接收用户输入了, 使用 相关的方法 System.out.println("请输入名字"); //当程序执行到 next 方法时,会等待用户输入~~~ String name = myScanner.next(); //接收用户输入字符串 System.out.println("请输入年龄"); int age = myScanner.nextInt(); //接收用户输入int System.out.println("请输入薪水"); double sal = myScanner.nextDouble(); //接收用户输入double System.out.println("人的信息如下:"); System.out.println("名字=" + name + " 年龄=" + age + " 薪水=" + sal); } }
Map
HashMap
import java.util.HashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "小明"); //使用put方法添加键值对,返回值我们会在后面讨论 map.put(2, "小红"); map.put(4, "coleak"); System.out.println(map.get(2)); //使用get方法根据键获取对应的值 map.remove(2); System.out.println(map); System.out.println(map.keySet()); System.out.println(map.values()); } } import java.util.*; public class Main { public static void main(String[] args) { Map<Integer , String> map = new HashMap<>(); map.put(0, "单走"); map.replace(0, ">>>"); //直接替换为新的 System.out.println(map); } } public static void main(String[] args) { Map<Integer , String> map = new HashMap<>(); map.put(0, "单走"); map.replace(0, "巴卡", "玛卡"); //只有键和值都匹配时,才进行替换 System.out.println(map); }
import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "A"); map.put(2, "B"); map.compute(3, (k, v) -> { //compute会将指定Key的值进行重新计算,若Key不存在,v会返回null return v+"M"; //这里返回原来的value+M }); map.computeIfPresent(3, (k, v) -> { //当Key存在时存在则计算并赋予新的值 return v+"M"; //这里返回原来的value+M }); System.out.println(map); } }
{1=A, 2=B, 3=nullMM}
import java.util.*; public class Main { public static void main(String[] args) { List<Student> students = Arrays.asList( new Student("yoni", "English", 80), new Student("yoni", "Chiness", 98), new Student("yoni", "Math", 95), new Student("taohai.wang", "English", 50), new Student("taohai.wang", "Chiness", 72), new Student("taohai.wang", "Math", 41), new Student("Seely", "English", 88), new Student("Seely", "Chiness", 89), new Student("Seely", "Math", 92) ); Map<String, Integer> scoreMap = new HashMap<>(); //merge方法可以对重复键的值进行特殊操作 students.forEach(student -> scoreMap.merge(student.getName(), student.getScore(), Integer::sum)); scoreMap.forEach((k, v) -> System.out.println("key:" + k + "总分" + "value:" + v)); } static class Student { private final String name; private final String type; private final int score; public Student(String name, String type, int score) { this.name = name; this.type = type; this.score = score; } public String getName() { return name; } public int getScore() { return score; } public String getType() { return type; } } }
LinkedHashMap
如果需要维护顺序,我们同样可以使用LinkedHashMap,它的内部对插入顺序进行了维护
import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<String , String> map = new LinkedHashMap<>(); map.put("0", "十七张"); map.put("+", "牌"); map.put("P", "你能秒我"); System.out.println(map); System.out.println(map.keySet()); System.out.println(map.values()); } }
{0=十七张, +=牌, P=你能秒我}
[0, +, P]
[十七张, 牌, 你能秒我]
Stream流
stream()
import java.util.*; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); //Stream操作 list = list //链式调用 .stream() //获取流 .filter(e -> !e.equals("B")) //只允许所有不是B的元素通过流水线 .collect(Collectors.toList()); //将流水线中的元素重新收集起来,变回List System.out.println(list); } }
import java.util.*; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(3); System.out.println(list); list = list .stream() .distinct() //去重(使用equals判断) .sorted((a, b) -> b - a) //进行倒序排列 .map(e -> e+10) //每个元素都要执行+1操作 .limit(2) //只放行前两个元素 .collect(Collectors.toList()); System.out.println(list); } }
[1, 2, 3, 3]
[13, 12]
stream会先记录每一步操作,而不是直接开始执行内容,当整个链式调用完成后,才会依次进行
ints()
import java.util.Random; public class Main { public static void main(String[] args) { Random random = new Random(); random .ints(-100, 100) //生成-100~100之间的,随机int型数字(本质上是一个IntStream) .limit(10) //只获取前10个数字(这是一个无限制的流,如果不加以限制,将会无限进行下去!) .filter(i -> i < 0) //只保留小于0的数字 .sorted() //默认从小到大排序 .forEach(System.out::println); //依次打印 } }
import java.util.IntSummaryStatistics; import java.util.Random; public class Main { public static void main(String[] args) { Random random = new Random(); //Random是一个随机数工具类 IntSummaryStatistics statistics = random .ints(0, 100) .limit(1000) .summaryStatistics(); //获取语法统计实例 System.out.println(statistics.getMax()); //快速获取最大值 System.out.println(statistics.getCount()); //获取数量 System.out.println(statistics.getAverage()); //获取平均值 } }
import java.util.*; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("A,B"); list.add("C,D"); list.add("E,F"); //我们想让每一个元素通过,进行分割,变成独立的6个元素 list = list .stream() //生成流 .flatMap(e -> Arrays.stream(e.split(","))) //分割字符串并生成新的流 .collect(Collectors.toList()); //汇成新的List System.out.println(list); //得到结果 } }
[A, B, C, D, E, F]
Collections工具类
import java.util.*; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<Integer> list = Arrays.asList(2, 3, 8, 9, 10, 13); System.out.println(Collections.binarySearch(list, 8)); System.out.println(Collections.max(list)); Collections.fill(list, 6); System.out.println(list); List<Integer> list2 = new ArrayList<>(Arrays.asList(1,2,3,4,5)); System.out.println(Collections.indexOfSubList(list2, Arrays.asList(4, 5))); } }
2
13
[6, 6, 6, 6, 6, 6]
3