Java数组、字符串与集合


Java集合是前人为我们提供的一套用于存储数据和对象的工具,如果你学过C++的STL,可以与之类比。Java集合大致可以分为List、Set、Map三类,分别对应于数据结构中的线性表、不相交集、映射(哈希表),注意java中一般称Set为集而非集合(Java核心卷1所述)。

1. 数组

  • 求长度
int len = arr.length;
  • 数组转列表
// data为int[]类型的数组
List<Integer> list1 = Arrays.stream(data).boxed().collect(Collectors.toList());

// Integer[]数组 ;利用asList方法(这种方法不适用于基础类型的数组)
List<String> lis=Arrays.asList(arr)  // arr为String[]数组
ArrayList<String> arrayList = new ArrayList(Arrays.asList(arr));
  • 数组合并
    将数组转为列表再利用addAll方法合并。
对于String[] 数组
List<String> lis1=Arrays.asList(arr1)  // arr1为String[]数组
List<String> lis2=Arrays.asList(arr2)  // arr2为String[]数组
lis1.addAll(lis2);
//再将合并好的列表转为数组
String[] res=lis1.toArray(new String[lis1.size()]);

对于基本类型数组
List<Integer> list1 = Arrays.stream(data1).boxed().collect(Collectors.toList());
List<Integer> list2 = Arrays.stream(data2).boxed().collect(Collectors.toList());
list1.addAll(list2);
int[] res = list1.stream().mapToInt(Integer::intValue).toArray();
  • 基本类型数组<——>包裹类型数组
// data为int[]数组
Integer[] integers1 = Arrays.stream(data).boxed().toArray(Integer[]::new);
// integers1为Integer[]数组
int[] arr2 = Arrays.stream(integers1).mapToInt(Integer::valueOf).toArray();
  • 求数组sum、max
//array是int[]数组
int sum=Arrays.stream(array).sum();//求数组所有元素之和
int max=Arrays.stream(maxj).max().getAsInt();//求数组所有元素最大值
  • 数组切片
int[] test_int = new int[] { 1, 2, 3, 4, 5};
test_int = Arrays.copyOfRange(test_int, 1, 4);// 返回[1,4)之间的子数组    
System.out.println(Arrays.toString(test_int));//数组转字符串

2. 字符串

  • 字符串基本操作
// String s;
int len = s.length();//求长度
String sub = s.substring(int begin,int end);//取[begin,end)之间的字符串,如果只给了begin,则end默认到原字符串末尾
char c = s.charAt(int index);//取第index个字符
int r = s.compareTo(s1);//r小于0代表s<s1,其余类推
boolean b = s.contains(s1);//s是否包含子字符串s1
String s="123456";int b=Integer.parseInt (s);//字符串转整数
  • StringBuffer和StringBuilder
    • String 是不可变的,而 StringBuffer 和 StringBuilder 是可变类。
    • StringBuffer 是线程安全和同步的,而 StringBuilder 不是。这就是 StringBuilder 比 StringBuffer 快的原因。
    • 字符串连接运算符 (+) 在内部使用 StringBuilder 类。
    • 对于非多线程环境中的字符串操作,我们应该使用 StringBuilder 而非使用 StringBuffer 类。
//StringBuilder 中的常用函数方法
append(); 在字符串末尾追加对象 如 str.append(“xuning”);
insert(3,!) 在字符串str的第4个位置(索引3)插入! str.insert(3,!);
toString();Stringbuilder转化为String

3. List

List:列表,是一个接口。它的实现类常用的有LinkedList、ArrayList和Vector。

3.1 LinkedList

  • LinkedList采用双向链表实现的列表,因此可以被用作队列、堆栈、双端队列;顺序访问高效,随机访问性能较差、适用于需要经常添加和删除的数据。
  • LinkedList不支持同步
LinkedList<Integer> linked = new LinkedList<>();//新建空链表
int len=linked.size();//获取链表长度
linked.add(1);//在链表末尾添加元素
linked.addFirst(10);//在链表首部添加元素
linked.add(1,20);//在索引1(从0开始计)处添加元素20,原先1处及之后元素后移一位
int i=linked.remove(1);//删除索引1处的元素,并返回该元素
int i=linked.get(1);//获取索引1处的元素

3.2 ArrayList

  • ArrayList是采用数组实现的列表,因此它支持随机访问,不适合频繁删除和插入操作。对于需要经常进行查询的数据建议采用此结构。
  • ArrayList与java数组的一个大的区别是ArrayList能够自动扩容
  • ArrayList不支持同步
ArrayList<Integer> array = new ArrayList<>();
int len=array.size();//获取长度
array.add(0); //在ArrayList末尾添加元素;int会自动装箱,转为Integer;
				//允许有相同的元素;注意ArrayList没有addFirst方法
array.add(1,9);//在索引1(从0开始计)处添加元素9,原先1处及之后元素后移一位
int ele=array.get(1);//获取索引1处的元素

3.3 Vector

Vector用法和ArrayList用法很相似,它们的区别在于Vector是线程同步的,而且Vector有另外的遍历方式。

3.4 List

List是一个接口。可以将LinkedList、ArrayList和Vector的对象赋给List变量。

  • 初始化
List<Integer> list1=new LinkedList<>();
List<Integer> list2=new ArrayList<>();
List<Integer> list3=new Vector<>();
  • 列表转数组
List<Integer> list = new ArrayList<>();
// 利用java的Stream
int[] res = list.stream().mapToInt(Integer::intValue).toArray();
// 也可以直接转为Integer数组
Integer[] integer = list.toArray(new Integer[list.size()]);
// 如果上面这句不行的话可以试试加上强制类型转换
String[] arr = (String[])list.toArray(new String[size]);

  • 列表排序
//ans为容器,例如List<Integer>,所装元素必须实现Comparable接口.
Collections.sort(ans); //直接改变ans本身
  • 列表切片
    注意:test_list.subList()返回的是List。
List<Integer> test_list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
List<Integer> test_list_2 = test_list.subList(1, 4);//返回[1,4)之间的子列表
System.out.println(test_list_2);

4. 队列

  • 队列是一种比较特殊的线性结构。它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。
  • 队列中最先插入的元素也将最先被删除,对应的最后插入的元素将最后被删除。因此队列又称为“先进先出”(FIFO—first in first out)的线性表,与栈(FILO-first in last out)刚好相反。
  • ArrayDeque采用数组的实现方式,LinkedList采用链表的实现方法。如果数据量较大,则使用LinkedList,否则优先使用ArrayDeque.
  • ArrayDeque < E> 和LinkedList< E>都实现了双端队列Deque,可以使用ArrayDeque< E>或LinkedList< E>实现栈和队列的功能。

4.1 Queue

  • 队列基本操作(新建队列、入队、出队等)
    offer、poll、peek这三个方法是推荐使用的
Queue<String> q=new ArrayDeque<>();//定义队列
Queue<String> q=new LinkedList();//LinkedList更常用
q.offer(start);//入队;超出容量限制会返回false
q.add(start);//入队;超出容量限制会报异常
q.poll();//出队
q.remove();//出队,失败时抛出异常
q.peek();//查看栈顶元素;队列是空返回null
q.element();//查看栈顶元素;队列是空就抛出异常NoSuchElementException

4.2 ArrayDeque

这里介绍一下ArrayDeque这个类

  • ArrayDeque不是线程安全的。
  • ArrayDeque不可以存取null元素,因为系统根据某个位置是否为null来判断元素的存在。
  • 当作为栈使用时,性能比Stack好;当作为队列使用时,性能比LinkedList好。
1.添加元素
        addFirst(E e)在数组前面添加元素
        addLast(E e)在数组后面添加元素
        offerFirst(E e) 在数组前面添加元素,并返回是否添加成功
        offerLast(E e) 在数组后天添加元素,并返回是否添加成功
2.删除元素
        removeFirst()删除第一个元素,并返回删除元素的值,如果元素为null,将抛出异常
        pollFirst()删除第一个元素,并返回删除元素的值,如果元素为null,将返回null
        removeLast()删除最后一个元素,并返回删除元素的值,如果为null,将抛出异常
        pollLast()删除最后一个元素,并返回删除元素的值,如果为null,将返回null
        removeFirstOccurrence(Object o) 删除第一次出现的指定元素
        removeLastOccurrence(Object o) 删除最后一次出现的指定元素
3.获取元素
        getFirst() 获取第一个元素,如果没有将抛出异常
        getLast() 获取最后一个元素,如果没有将抛出异常
4.队列操作
        add(E e) 在队列尾部添加一个元素
        offer(E e) 在队列尾部添加一个元素,并返回是否成功
        remove() 删除队列中第一个元素,并返回该元素的值,如果元素为null,将抛出异常(其实底层调用的是removeFirst())
        poll()  删除队列中第一个元素,并返回该元素的值,如果元素为null,将返回null(其实调用的是pollFirst())
        element() 获取第一个元素,如果没有将抛出异常
        peek() 获取第一个元素,如果返回null
5.栈操作
        push(E e) 栈顶添加一个元素
        pop(E e) 移除栈顶元素,如果栈顶没有元素将抛出异常
6.其他
        size() 获取队列中元素个数
        isEmpty() 判断队列是否为空
        iterator() 迭代器,从前向后迭代
        descendingIterator() 迭代器,从后向前迭代
        contain(Object o) 判断队列中是否存在该元素
        toArray() 转成数组
        clear() 清空队列
        clone() 克隆(复制)一个新的队列

5. 栈

Java堆栈Stack类已经过时,Java官方推荐使用Deque替代Stack使用。Deque堆栈操作方法:push()、pop()、peek()

Deque deque = new LinkedList();

6. 优先队列

PriorityQueue类是一种队列数据结构实现,其中根据优先级处理对象。它与遵循FIFO(先进先出)算法的标准队列不同。

//容器中元素必须可比较(即实现Comparable接口)
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();

7. Set

HashSet

  • 基于散列函数的集和,采用HashMap实现,可以容纳null元素,不支持同步(可以通过Collections.synchronizedSet(new HashSet<…>()来使它同步)
Set<String> set1 = new HashSet<String>();// 新建一个空set
set1.retainAll(set2);//求交集
set1.removeAll(set2);//求差集(set1中移除掉set2中所有元素)
set1.addAll(set2);//求并集
set1.add("str");//加入元素;返回boolean值

LinkedHashSet

  • 继承HashSet ,基于散列函数和双向链表的集和,可以容纳null元素,通过双向链表维护了插入顺序,从而支持排序,但不支持同步(可以通过Collections.synchronizedSet(new HashSet<…>()来使它同步)
  • 使用方法和HashSet一致,区别在于LinkedHashSet的索引顺序与插入顺序一致(HashSet是随机乱序)

TreeSet

  • 基于树结构的集合,支持排序,不能容纳null元素,同样不支持同步
  • 按照从小到大的顺序排列,因为Integer实现了Compareable接口,默认从小到大。TreeSet的顺序就是基于Compareable接口或者Comparetor比较器
  • 添加到TreeSet里面的元素都必须实现comparable接口。因为在添加元素时会调用接口里面的compareTo()方法来比较是否是同一个元素。
TreeSet<Integer> ts = new TreeSet<>();

8. Map

Hashtable

  • key和value都不能为空,HashTable是线程安全的、同步的,但只适合用于小数据量

HashMap

  • HashMap允许有null,不支持同步(支持通过Collections.synchronizedMap(new Map<…,…>() 实现同步),所以线程不安全。但可以存储大量数据
HashMap<Integer,String> map=new HashMap<>();//新建哈希表
map.put(1,"words");//插入键值对

TreeMap

基于红黑树的Map,可以根据key的自然排序或者compareTo方法排序输出

Properties

继承自Hashtable。特有的方法有load()、store()等等。

LinkedHashMap

基于双向链表用于维持插入顺序的HashMap,继承自HashMap

9.工具类

Arrays

Arrays处理的对象是数组,常用的方法包括排序sort、查找binarySearch、拷贝copy等等

int[] a;
Arrays.sort(a);
int i = Arrays.binarySearch(a, 100);
Arrays.fill(a,1);//填充所有元素
Arrays.fill(a,2,8,100); //将[2,8)索引的元素填充为100
int[] ints1 = Arrays.copyOf(a, 4);//copy前4个元素,改参数不可省略(必须指定长度)
Arrays.equals(a,b)//判断两个数组的值是否完全相等,返回boolean

Collections

Collections可以操作collections接口及其所有子类、常用的用法和Arrays差不多。但它的sort方法要求被排序对象实现了compareable接口或者传入一个compactor对象(主要针对某些类不能去被修改)

  • Collections.sort(用于排序)
List<int[]> trees = new ArrayList<>();

使用比较器Comparator
trees.sort(new Comparator<int[]>() {
	@Override
	public int compare(int[] a, int[] b) {
		return forest.get(a[0]).get(a[1]) - forest.get(b[0]).get(b[1]);
	}
});
可以转换为lambda表达式
trees.sort((a, b) -> forest.get(a[0]).get(a[1]) - forest.get(b[0]).get(b[1]));

使用Collections类中的sort方法
Collections.sort(trees,(a, b) -> forest.get(a[0]).get(a[1]) - forest.get(b[0]).get(b[1]));
  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冷冰殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值