【蓝桥杯】Java组必备API类 --常用数据结构及自定义排序

在这里插入图片描述

Java数据结构

Java一共有 种数据结构时我们常用的,分别是以下几种

集合类型描述
ArrayList可以动态增长和缩减的序列,类似于C++的vector
LinkedList可以在任何位置高效插入和删除的有序序列,链表
ArrayDeque实现为循环数组的一个双端队列
HashSet没有重复元素的无序集合
TreeSet没有重复元素的有序集合
LinkedHashSet记住元素插入次序的集合
PriorityQueue优先队列
HashMap<K,V>型无序集合
TreeMap<K,V>型有序集合
LinkedHashMap记住添加次序的<K,V>型集合

以上所有数据结构都有以下这几种方法,需要记牢

boolean add(E e) 
//确保此集合包含指定的元素(可选操作)  
boolean addAll(Collection<? extends E> c) 
//将指定集合中的所有元素添加到此集合(可选操作)  
void clear() 
//从此集合中删除所有元素(可选操作)  
boolean contains(Object o) 
//如果此集合包含指定的元素,则返回 true   
boolean containsAll(Collection<?> c) 
//如果此集合包含指定 集合中的所有元素,则返回true  
boolean equals(Object o) 
//将指定的对象与此集合进行比较以获得相等性  
int hashCode() 
//返回此集合的哈希码值  
boolean isEmpty() 
//如果此集合不包含元素,则返回 true   
Iterator<E> iterator() 
//返回此集合中的元素的迭代器  
default Stream<E> parallelStream() 
//返回可能并行的 Stream与此集合作为其来源  
boolean remove(Object o) 
//从该集合中删除指定元素的单个实例(如果存在)(可选操作)  
boolean removeAll(Collection<?> c) 
//删除指定集合中包含的所有此集合的元素(可选操作)  
default boolean removeIf(Predicate<? super E> filter) 
//删除满足给定谓词的此集合的所有元素  
boolean retainAll(Collection<?> c) 
//仅保留此集合中包含在指定集合中的元素(可选操作)  
int size() 
//返回此集合中的元素数  
default Spliterator<E> spliterator() 
//创建一个Spliterator在这个集合中的元素  
default Stream<E> stream() 
//返回以此集合作为源的顺序 Stream   
Object[] toArray() 
//返回一个包含此集合中所有元素的数组  
<T> T[] toArray(T[] a) 
//返回包含此集合中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型  
ArrayList
ArrayList<Integer> list = new ArrayList<>();  //创建一个ArrayList
list.add(1);  //向ArrayList中添加元素
list.addAll(list1);  //向ArrayList中插入新的ArrayList

try {
	list.add(1,2);  //将2插入到第一个元素中,第一个元素到最后一个元素依次往后移
    list.addAll(1,list1)  //将list1中所有元素插入到list的第一个里面
} catch (IndexOutOfBoundsException e) {
	//如果第一个数字 > list.size() 则会抛出异常
}
list.get(0);  //向ArrayList中获取第0个元素
list.set(0,2);  //将第0个元素设置为2
list.clear();  //清空list
boolean b = list.contains(1);  //判断list中是否含有1
boolean b = list.isEmpty();  //判断list是否为空
int i = list.indexOf(1);  //查询list中第一次出现1的位置下标,没有则返回-1
int i = list.lastIndexOf(1);  //查询list中最后出现1的位置下标,没有则返回-1

int x = list.remove(0);  //删除第0号元素,同时将第0号元素的值返回
boolean b = list.remove(new Integer(3));  //删除list中第一个出现3的元素
/*
 * 当list为Integer类型是,list.remove(0)会被认为删除第0号元素而不是删除第一个出现0的元素
*/
System.out.prinltn(list.size());  //输出list的size大小
LinkedList

LinkedList的操作和ArrayList差不多,这里记录一些ArrayList中没有的一些API

void addFirst(E e) 
在该列表开头插入指定的元素  
void addLast(E e) 
将指定的元素追加到此列表的末尾 
boolean contains(Object o) 
如果此列表包含指定的元素,则返回 true   
Iterator<E> descendingIterator() 
以相反的顺序返回此deque中的元素的迭代器  
E getFirst() 
返回此列表中的第一个元素  
E getLast() 
返回此列表中的最后一个元素  
LinkedList和ArrayList的区别

LinkedList就是链表,ArrayList就是数组

LinkedList插入和删除中间的元素十分方便,但是随机访问的能力很弱

ArrayList插入和删除中间的元素开销大,但是随机访问的能力很强

Stack
Stack<Integer> stack = new Stack<>();  //创建一个新stack
stack.push(1);  //将1压入到stack中
int x = stack.peek();  //获取栈顶元素并且不使栈顶元素出栈
int x = stack.pop();  //获取栈顶元素并且使得栈顶元素出栈
int x = stack.search(1);  //查找离栈顶元素最近的1离栈顶的位置
eg: 1 2 3 4 5 1 2 3 4 5
stack.search(1);  //返回值为3
stack.search(5);  //返回值为5
eg: 1 2 3 4 5
stack.search(5);  //返回值为-1
boolean empty() 
//测试此堆栈是否为空  
E peek() 
//查看此堆栈顶部的对象,而不从堆栈中删除它  
E pop() 
//删除此堆栈顶部的对象,并将该对象作为此函数的值返回  
E push(E item) 
//将项目推送到此堆栈的顶部  
int search(Object o) 
//返回一个对象在此堆栈上的基于1的位置  

Set

set可以先不声明自己的泛型,这样的set可以插入不同的类,如下所示

HashSet s = new HashSet();
s.add("Polaris111");
s.add(123456);
s.add(new BigDecimal(123.456));
System.out.println(s);

打印出来的结果如下所示

Java的set一共分为两类,不能排序HashSet和能够排序的TreeSet,接下来让我分别介绍这两个类

HashSet
基本操作
HashSet<String> s = new HashSet<>();
s.add("str1");  //添加
s.add("str2");
s.add("str3");
System.out.println(s.isEmpty());  //判空
System.out.println(s.contains("str1"));  //判断集合是否包含元素
System.out.println(s.size());  //集合中元素个数
System.out.println(s.remove("str1"));  //删除元素
s.clear();  //清空所有元素

输出结果如下所示

在这里插入图片描述

遍历
//第一种
Iterator it = s.iterator();
while(it.hasNext()) {
    if(it.next().equals("str2")) {
		it.remove();
    }
}
//第二种
for(String str : s) {
    System.out.println(s);
}
TreeSet

TreeSet的内部实现是红黑树,基本操作方式和HashSet相同基本相同

TreeSet<String> s = new TreeSet<>();
s.add("str1");  //添加
s.add("str2");
s.add("str3");
System.out.println(s.isEmpty());  //判空
System.out.println(s.contains("str1"));  //判断集合是否包含元素
System.out.println(s.size());  //集合中元素个数
System.out.println(s.remove("str1"));  //删除元素
s.clear();  //清空所有元素

输出结果如下所示

在这里插入图片描述

遍历
//第一种
Iterator it = s.iterator();
while(it.hasNext()) {
    if(it.next().equals("str2")) {
		it.remove();
    }
}
//第二种
for(String str : s) {
    System.out.println(s);
}
HashMap
HashMap<Integer, String> hashMap = new HashMap<>();  //创建元素
hashMap.put(1, "test1");  //插入元素
hashMap.put(2, "test2");
hashMap.put(3, "test3");
System.out.println(hashMap.get(1));  //取元素
System.out.println(hashMap.isEmpty());  //判空
System.out.println(hashMap.size());  //输出元素数量
//判断键是否存在
if(hashMap.containsKey(1)) {
	System.out.println("1存在");
}
//判断值是否存在
if(hashMap.containsValue("test1")) {
	System.out.println("test1存在");
}
hashMap.remove(1);  //删除Key为1的元素
hashMap.remove(2,"test2");  //删除Key为2且值为test2的元素
hashMap.replace(3, "test4");  //将Key为3的元素的Value替换为"test4"
hashMap.replace(3, "test4", "test5");  //将Key为3且Value为"test4"的值替换为"test5"
Set<Map.Entry<Integer, String>> set = hashMap.entrySet();  //获取键
Iterator iterator = set.iterator();
while(iterator.hasNext()) {
	Map.Entry<Integer, String> it = (Entry<Integer, String>) iterator.next();
	System.out.println(it.getKey());  //取键
	System.out.println(it.getValue());  //取值
	System.out.println(it.setValue("null"));  //重新设置值
}
TreeMap

TreeMap的操作与HashMap差不多,这里我写几个TreeMap特有的操作

TreeMap<Integer, String> treeMap = new TreeMap<>();  //创建元素
treeMap.put(1, "test1");  //插入元素
treeMap.put(2, "test2");
treeMap.put(3, "test3");
Integer integer = treeMap.ceilingKey(3);  //  返回大于或等于给定键的键,如果没有此键,则返回null
System.out.println(integer);
Map.Entry<Integer, String> entry = treeMap.ceilingEntry(3);  //  返回与大于或等于给定键的最小键相关联的键值映射,如果没有此键,则返回null
System.out.println(entry.getKey());  //取键
System.out.println(entry.getValue());  //取值

TreeMap在寻找值除了上述的操作外还有以下的操作:

Map.Entry<K,V> ceilingEntry(K key) 
//返回与大于或等于给定键的最小键相关联的键值映射,如果没有此键,则 null
K ceilingKey(K key) 
//返回大于或等于给定键的 null键,如果没有此键,则返回 null  
Map.Entry<K,V> firstEntry() 
//返回与该地图中的最小键相关联的键值映射,如果地图为空,则返回 null   
K firstKey() 
//返回此地图中当前的第一个(最低)键  
Map.Entry<K,V> floorEntry(K key) 
//返回与小于或等于给定键的最大键相关联的键值映射,如果没有此键,则 null   
K floorKey(K key) 
//返回小于或等于给定键的最大键,如果没有这样的键,则返回 null   
SortedMap<K,V> headMap(K toKey) 
//返回此地图部分的视图,其密钥严格小于 toKey   
NavigableMap<K,V> headMap(K toKey, boolean inclusive) 
//返回此地图部分的视图,其键值小于(或等于,如果 inclusive为真) toKey   
Map.Entry<K,V> higherEntry(K key) 
//返回与最小密钥相关联的密钥值映射严格大于给定密钥,如果没有这样的密钥则 null   
K higherKey(K key) 
//返回严格大于给定键的最小键,如果没有这样的键,则返回 null   
Map.Entry<K,V> lastEntry() 
//返回与该地图中最大关键字关联的键值映射,如果地图为空,则返回 null   
K lastKey() 
//返回当前在此地图中的最后(最高)键  
Map.Entry<K,V> lowerEntry(K key) 
//返回与最大密钥相关联的密钥值映射严格小于给定密钥,如果没有这样的密钥,则 null   
K lowerKey(K key) 
//返回严格小于给定键的最大键,如果没有这样的键,则返回 null   
Map.Entry<K,V> pollFirstEntry() 
//删除并返回与该地图中的最小键相关联的键值映射,如果地图为空,则返回 null   
Map.Entry<K,V> pollLastEntry() 
//删除并返回与该地图中最大密钥相关联的键值映射,如果地图为空,则返回 null   
NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) 
//返回此地图部分的视图,其关键范围为 fromKey至 toKey   
SortedMap<K,V> subMap(K fromKey, K toKey) 
//返回此地图部分的视图,其关键字范围从 fromKey (含)到 toKey ,独占  
SortedMap<K,V> tailMap(K fromKey) 
//返回此地图部分的视图,其键大于等于 fromKey   
NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) 
//返回此地图部分的视图,其键大于(或等于,如果 inclusive为真) fromKey   

PriorityQueue

PriorityQueue默认小根堆,要想生成大根堆,可以按照如下方式生成。

PriorityQueue<Integer> priorityQueue = new PriorityQueue<>((x,y) -> (y-x));
基本操作
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
priorityQueue.offer(1);  //插入元素
priorityQueue.offer(2);
priorityQueue.offer(3);
priorityQueue.offer(4);
priorityQueue.offer(5);
System.out.println(priorityQueue.poll());  //查找队头并删除队头
System.out.println(priorityQueue.peek());  //查找队头
System.out.println(priorityQueue.size());  //输出元素数量
priorityQueue.remove(4);  //删除元素如果存在

自定义排序

HashSet可以自定义排序函数,也可以让HashSet排序的类里面重载compareTo函数,操作如下所示

public int compare(String o1, String o2):比较其两个参数的顺序

    static class MyClass {
        public int f;
        public int s;
    }

    static class MyComparator implements Comparator<MyClass> {
        @Override
        public int compare(MyClass o1, MyClass o2) {
            if(o1.f != o2.f) {
                if(o1.f > o2.f) {
                    return 1;
                } else {
                    return -1;
                }
            } else {
                if(o1.s > o2.s) {
                    return 1;
                } else {
                    return -1;
                }
            }
        }
    }

两个对象比较的结果有三种:大于,等于,小于

如果要按照升序排序,
则o1 小于o2,返回(负数),相等返回0,01大于02返回(正数)
如果要按照降序排序
则o1 小于o2,返回(正数),相等返回0,01大于02返回(负数)

做如下测试,可以看到TreeSet按照我们给提供的接口去进行排序的

TreeSet<MyClass> treeSet = new TreeSet<>(new MyComparator());
        treeSet.add(new MyClass(1, 2));
        treeSet.add(new MyClass(2, 2));
        treeSet.add(new MyClass(2, 3));
        treeSet.add(new MyClass(4, 3));
        treeSet.add(new MyClass(5, 6));
        treeSet.add(new MyClass(7, 3));
        Iterator it = treeSet.iterator();
        while(it.hasNext()) {
            System.out.println(it.next().toString());
        }

在这里插入图片描述

也可以在声明类的时候继承Comparable接口来自定义排序方法,这样TreeSet这种排序集合在排序的时候就会执行我们自定义类中的方法

static class MyClass implements Comparable<MyClass> {
        public int f;
        public int s;

        @Override
        public int compareTo(MyClass o) {
            if(this.f != o.f) {
                if(this.f > o.f) {
                    return 1;
                } else {
                    return -1;
                }
            } else {
                if(this.s > o.s) {
                    return 1;
                } else {
                    return -1;
                }
            }
        }
    }

同样是进行和上面一样的测试,可以发现结果是一样的,TreeSet这种排序集合在排序的时候就会执行类中的compareTo方法

TreeSet<MyClass> treeSet = new TreeSet<>();
        treeSet.add(new MyClass(1, 2));
        treeSet.add(new MyClass(2, 2));
        treeSet.add(new MyClass(2, 3));
        treeSet.add(new MyClass(4, 3));
        treeSet.add(new MyClass(5, 6));
        treeSet.add(new MyClass(7, 3));
        Iterator it = treeSet.iterator();
        while(it.hasNext()) {
            System.out.println(it.next().toString());
        }

结果如下所示

[外链图片转存中...(img-GYaJayDk-1648902874793)]

如果二者都不定义直接排序呢?答案是不可以的,编译器会报如下的错误:
在这里插入图片描述

  • 2
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值