String

Java.lang.String是Java的字符串类. Srting是一个不可变对象,所有对String修改的操作都需要构造新的String实例.

String可以由char数组或字符串字面值来构造:

char[] data = {'a', 'b', 'c'}
String s = new String(data)
String s = "Hello World";
String s = new String("Hello World");

使用+运算符可以连接两个字符串:

String s = "Hello" + "World";

比较字符串

Java中的==运算符用于比较两个引用是否指向了同一个对象:

String s1 = new String("Hello World");
String s2 = new String("Hello World");
System.out.println(s1 == s2);  // false

上述程序输出为false, 因为s1和s2指向了不同对象. 若要比较字符串内容是否相同, 请使用equals方法:

String s1 = new String("Hello World");
String s2 = new String("Hello World");
System.out.println(s1.equals(s2)); // true

结果为true没什么需要解释的. 下面这个代码的结果就比较有意思了:

String s1 = "Hello World";
String s2 = "Hello World";
System.out.println(s1 == s2);  // true

结果为true, 说明s1和s2指向了同一个对象. Java在存储字符串字面值时, 会先检查内存中是否存在相同对象. 若存在就直接将新的引用指向该对象.

方法

我们常用format方法以格式化的方式创建新字符串:

System.out.println(String.format("user:%s, age:%d", "abc", 12));

String提供了一系列方法:

  • s.charAt(int): 返回某个位置的字符, 下标从0开始

  • s.length(): 返回字符串的长度

  • s.matches(String regex): 检查字符串时候符合正则表达式regex定义的模式, 返回boolean.
    "A123".matches("[a-zA-Z][0-9]*");

  • s.substring(int start, int end): 返回[start, end)范围内的子串, 若省略end则返回剩余全部字符串.
    "HelloWorld".substring(5, 7); //Wo
    HelloWorld".substring(5); //World

类型转换

  • s.getBytes(): 转换为bytes[]

  • s.toCharArray(): 转换为char[]

  • Integer.parseInt(s): 转换为int

  • Double.parseDouble(s): 转换为double

StringBuffer 与 StringBuilder

java.lang.StringBufferjava.lang.StringBuilder是可变的字符串对象.

StringBuilder较快但是线程不安全的, 在对线程安全没有要求时我们通常使用StringBuilder.

它们拥有和String类似的方法, 并提供了动态操作的API:

  • sb.append(String): 将字符串追加到末尾.

  • sb.reverse(): 字符串反向

  • sb.delete(start, end): 删除[start, end)范围内的字符

  • sb.insert(i, seq): 将字符序列插入i位置

  • sb.replace(start, end, str): 用str替换[start, end)处的字串

Array

Java对所有数据类型都提供了内置的数组支持. 数组是定长的, 下标从0开始.

数组有两种声明方式:

int[] arr = new int[5];

不建议使用下面这种方式:

int arr[] = new int[5];

也可以直接使用数组字面值:

int[] arr = {1, 2, 3};

length()方法用于获取长度, []运算符可以访问或修改某个元素:

arr[0] = 2;
i = arr[1];

Java很容易实现多维数组:

int[][] mat = new int[5][5];
mat[2][2] = 1;

java.util.Arrays提供了一些操作数组的工具:

  • Arrays.fill(arr, val): 将数组arr中所有元素设为val

  • Arrays.binarySearch(arr, key): 在数组arr用二分法查找元素key, arr必须已经排好序. 找到返回索引, 否则返回-1.

  • Arrays.equals(arr1, arr2): 判断arr1和arr2中的内容是否相同

  • Arrays.sort(arr): 对数组进行升序排序.

foreach可以用于遍历数组:

int[] arr = {1, 2, 3};
for (int i : arr) {
    System.out.println(i);
}

List

Java Collection框架提供了各种容器的借口和实现, 所有容器类均采用泛型实现. 所有类均实现了iterable接口, 可以使用for-each遍历.

java.util.list是线性容器的interface, Java中提供了三种常用的实现:

  • java.util.ArrayList: 使用数组实现, 线程不安全

  • java.util.LinkedList: 使用链表实现, 线程不安全

  • java.util.vector: 线程安全实现

注意不能使用内置类型初始化, 必须使用封装类:

List<Integer> l = new ArrayList<Integer>(5);

list接口声明了以下方法:

  • l.get(i): 返回指定位置的元素, 下标从0开始

  • l.set(i, val): 设置指定位置的元素

  • l.size(): 返回容器中元素的个数

  • l.contains(e): 判断容器中是否包含指定元素val, 返回boolean值.

  • l.equals(c): 判断容器相同位置上的元素是否相同, 返回boolean值

  • l.add(i, e): 在指定位置插入元素val, 若省略i则在末尾插入

  • l.addAll(i, c): 在指定位置插入容器c中所有元素, 若省略i则在末尾插入

  • l.remove(i): 删除指定位置上的元素

  • l.clear(): 删除所有元素

  • l.clone(): 返回自身的浅拷贝副本

  • l.toArray(): 转换为相应类型的数组

list同样可以用foreach遍历:

List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
for (String s : list) {
    System.out.println(s);
}

Set

java.util.Set是无序的, 不允许重复的容器接口, 对应数学上的集合. Java提供了HashSetTreeSet两种实现.

Set<String> s = new HashSet<String>();

Set接口声明了下列方法:

  • s.contians(e): 判断容器中是否包含元素e, 返回boolean值

  • s.equals(c): 判断两个容器中包含的元素是否完全相同, 返回boolean值

  • l.size(): 返回容器中元素的个数

  • l.add(e): 添加元素val

  • l.addAll(c): 添加容器c中所有元素

  • l.remove(e): 删除指定的元素

  • l.clear(): 删除所有元素

  • l.clone(): 返回自身的浅拷贝副本

  • l.toArray(): 转换为相应类型的数组

foreach遍历集合:

Set<String> set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");
for (String s : set) {
    System.out.println(s);
}

Map

java.util.Map是保存键值对的容器, 键不允许重复. Java提供了HashMapTreeMap两种实现.

Map<String, Integer> m = new HashMap<String, Integer>();

Map接口声明了下列方法:

  • m.containsKey(key): 判断所有键中是否包含key, 返回boolean值

  • m.containsValue(val): 判断所有值中是否包含val, 返回boolean值

  • m.get(key): 返回key对应的值

  • m.put(key, val): 设置key对应的值为val, 若不存则新建

  • m.putAll(map): 加入map中所有键值对, 重复的进行覆盖

  • m.remove(key): 删除指定键值对

  • m.clear(): 删除所有键值对

  • m.keySet(): 返回所有键组成的java.util.Set

  • m.values(): 返回所有值组成的java.util.Collection

遍历Map需要Entry的帮助:

Map<String, String> map = new HashMap<>();
map.put("a", "1");
map.put("b", "2");
map.put("c", "3");
for (Map.Entry<String, String> entry : map.entrySet()) {
    System.out.println(entry.getKey() + ":" + entry.getValue());
}

Iterator

java.util.Iterator定义了迭代器接口, 在使用迭代器遍历容器时不需要了解容器的具体数据结构.

List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
Iterator<String> iter = list.iterator();
while(iter.hasNext()) {
    String str = iter.next();
    System.out.println(str);
}

iter.next()方法会返回游标指向的元素, 并将游标后移一位. iter.hasNext()用于检测是否完成了遍历.

iter.remove()方法可以删除迭代器上一次返回的元素, 通常迭代器无法添加元素.

迭代器由ArrayList等实现类提供, 上文提及的foreach遍历实际上是通过容器的迭代器实现的.

Set容器的迭代器示例:

Set<String> set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");
Iterator<String> iter = set.iterator();
while(iter.hasNext()) {
    String str = iter.next();
    System.out.println(str);
}

Map容器的迭代器同样依赖于EntrySet:

Map<String, String> map = new HashMap<>();
map.put("a", "1");
map.put("b", "2");
map.put("c", "3");
Iterator<Map.Entry<String, String>> iter = map.entrySet().iterator();
while (iter.hasNext()) {
    Map.Entry<String, String>  entry = iter.next();
    System.out.println(entry.getKey() + ":" + entry.getValue());
}

ListIterator

List接口除了iterator()外还提供了功能更强的listIterator(). listIterator()拥有iterator()的全部功能, 并且可以双向遍历和添加元素.

List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
ListIterator<String> iter = list.listIterator();
while(iter.hasNext()) {
    String str = iter.next();
    System.out.println(str);
}
iter.add("d");
while(iter.hasPrevious()) {
    String str = iter.previous();
    System.out.println(str);
}

fail-fast && fail-safe

Collections框架中的常规容器使用fail-fast迭代器, 如ArrayListHashMap并发容器通常使用fail-safe迭代器.

fail-fast迭代器会记录容器发生结构性改变(添加删除元素)的次数, 若迭代过程中容器发生了结构性改变fail-fast迭代器会抛出运行时异常终止迭代.

迭代过程中的结构性改变通常是由于其它线程修改了容器, 终止迭代可以避免出现不一致的错误.

CopyOnWriteArrayListConcurrentHashMap等并发容器则使用fail-safe迭代器, fail-safe迭代器在容器的快照(snapshot)上进行遍历. 容器发生结构性改变时快照不受影响, fail-safe迭代器可以正常完成遍历.

相对于只提供访问接口不存储数据的fail-fast迭代器, fail-safe迭代器需要复制集合快照,产生较大开销. fail-safe迭代器基于快照的访问方式虽然可以在并发环境下正常遍历, 但无法保证访问到最新数据.

本文只对fail-fast与fail-safe迭代器进行简单介绍, 在各容器的源码解析中将进一步介绍迭代器的实现.

enum

Java使用enum关键字来定义枚举:

enum Season {
    Spring, Summer, Autum, Winter;
}

public class Main {

    public static void main(String[] args) {
        System.out.println(Season.Spring);  // print: Spring
    }
}

enum关键字与class关键字的地位相同, enum也可以定义其它属性和方法.

enum中的每个枚举值类似于一个实例, 我们可以在enum中为其定义构造方法.

enum Season {
    Spring(2, 4), Summer(5, 7), Autum(8, 10), Winter(11, 1);

    public int start;
    public int stop;

    private Season(int start, int stop) {
        this.start = start;
        this.stop = stop;
    }

}

public class Main {

    public static void main(String[] args) {
        System.out.println(Season.Spring);  // Spring
        System.out.println(Season.Spring.start); // 2
    }
}

注意, enum的构造器只能是私有的(private).

BitSet

java.util.BitSet是位的容器, 我们可以用它保存标志位等数据:

BitSet bs = new BitSet(5);

BitSet提供了一些方法用于操作:

  • bs.get(i): 以boolean的形式返回第i位, 下标从0开始

  • bs.get(start, end): 以BitSet的形式返回[start, end)中的字节.

  • bs.set(i, b): 将第i位设为布尔值b, 省略b时设为true.

  • bs.equals(c): 判断与容器c内容是否相同

  • bs.clear(): 将所有位设为false

  • bs.size(): 返回总位数

  • bs1.and(bs2): 进行位与运算, 返回BitSet

  • bs1.andNot(bs2): 进行位与非运算, 返回BitSet

  • bs1.or(bs2): 进行位或运算, 返回BitSet

  • bs1.xor(bs2): 进行位异或运算, 返回BitSet

Java字符串和容器的更多相关文章

  1. 为什么Java字符串是不可变对象?

    转自 http://developer.51cto.com/art/201503/468905.htm 本文主要来介绍一下Java中的不可变对象,以及Java中String类的不可变性,那么为什么Ja ...

  2. Java字符串String

    Java字符串String 我们知道Java的字符窜是Immutable(不可变)的,一旦创建就不能更改其内容了:平常我们对字符串的操作是最多的,其实对字符串的操作,返回的字符串都是新建的字符串对象, ...

  3. java字符串集合

    一,java的接口跟C语言所能做到的相比确实是让人眼前一亮的东西.利用接口可以将多种东西放到一起,在编程过程中就能省略掉相同类的很多重复代码,将代码进行分类别的,统一的处理. 二,java中的字符串处 ...

  4. Java字符串String 集合的迭代器

    Java字符串String 我们知道Java的字符窜是Immutable(不可变)的,一旦创建就不能更改其内容了:平常我们对字符串的操作是最多的,其实对字符串的操作,返回的字符串都是新建的字符串对象, ...

  5. Java 字符串格式化详解

    Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...

  6. Java多线程-并发容器

    Java多线程-并发容器 在Java1.5之后,通过几个并发容器类来改进同步容器类,同步容器类是通过将容器的状态串行访问,从而实现它们的线程安全的,这样做会消弱了并发性,当多个线程并发的竞争容器锁的时 ...

  7. (转)Java字符串

    转自:http://blog.sina.com.cn/s/blog_899678b90101brz0.html 创建字符串有两种方式:两种内存区域(字符串池,堆)1," " 引号创 ...

  8. 转:java多线程--同步容器

    java同步容器 在Java的集合容器框架中,主要有四大类别:List.Set.Queue.Map.List.Set.Queue接口分别继承了Collection接口,Map本身是一个接口.注意Col ...

  9. Java字符串split函数的注意事项

    Java字符串的split方法可以分割字符串,但和其他语言不太一样,split方法的参数不是单个字符,而是正则表达式,如果输入了竖线(|)这样的字符作为分割字符串,会出现意想不到的结果, 如, Str ...

随机推荐

  1. 《Miracle-House团队》第二次作业:西小餐项目开题报告

    一.本团队项目的NABCD评分结果汇总 小组名 N A B C D 总分 Just_Do_IT! 9 7 8 7 9 40 A-Pancers 8 8 8 9 7 40 ymm3  8 9 9 8 9 ...

  2. P1613 跑路(倍增 + floyd)

    https://www.luogu.org/problemnew/show/P1613 思路: 1.读入 2.建图 3.对于每一个点,向距离它 2^k 长度的点连一条长度为 1 的边 4.在新图上跑1 ...

  3. string所在头文件

    使用string.wstring 头文件:#include <string> 命名空间:std

  4. Do More With These Great Plugins for Windows Live Writer(old)

    This article is out of day,now we use open live wirter, but we don’t have so much works great plugin ...

  5. less的功能和介绍

    在全新的css中,经过程序员们的开发和努力.又打造了全新的less样式表的全新界面,只需引入外部样式表即刻套用,加上了函数定义和取值.大大的降低了代码的书写量.也更加方便程序员的调用和修改!

  6. ReactNative学习笔记(二)基础进阶

    一个最简单的HelloWorld页面 先不多解释,直接上代码: import React, { Component } from 'react'; import {AppRegistry, Style ...

  7. rpm is for architecture aarch64 ; the package cannot be built on this system

    问题:rpm is for architecture aarch64 ; the package cannot be built on this system $ sudo alien --to-de ...

  8. 2018/7/26号碰到了个奇怪的问题(http有问题,但是ftp没毛病)

    过程大概是这样的 本来测试服务器中发ajax没问题,突然暴毙了,服务器又通过ajax发了另外一个请求(与之前不一样). nginx  reload 没毛病  ,ftp 也使用正常. 出了什么问题呢?  ...

  9. vue高级组件之provide / inject

    转载:https://blog.csdn.net/Garrettzxd/article/details/81407199 在vue中不同组件通信方式如下 1.父子组件,通过prop 2.非父子组件,通 ...

  10. OpenStack-Ocata版+CentOS7.6 云平台环境搭建 — 2.安装配置OpenStack基础服务

    节点配置情况说明: 控制节点:controller: IP:192.168.164.128 hostname&hosts:likeadmin 计算加点:Nova: IP:192.168.164 ...