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. Codeforces 835C-Star sky

    题目链接:http://codeforces.com/problemset/problem/835/C 题意:天上有很多星星,每个星星有他自己的坐标和初始亮度,然后每个星星的亮度在一秒内会加一如果大于 ...

  2. hadoop启动

    安装完hadoop集群之后,第一次启动之前必须初始化,之后就可以不用再初始化(注意:初始化操作只可以一次) hdfs namenode -format (hadoop namenode -format ...

  3. 常见bat(批处理)命令的语法规则

    最近由于在做cocos2d的项目,需要用到一些bat命令,在此做些记录. bat命令用txt文本编辑就行,编辑完之后将后缀名改为bat即可运行.先来一个最简单的例子: @echo off echo \ ...

  4. 14. The Realities of Telecommuting 远程办公的现状

    14. The Realities of Telecommuting 远程办公的现状 (1) Telecommuting——substituting the computer for the trip ...

  5. centos7配置Hadoop集群环境

    参考: https://blog.csdn.net/pucao_cug/article/details/71698903 设置免密登陆后,必须重启ssh服务 systermctl restart ss ...

  6. ubuntu服务器搭建DVWA站点

    把DVWA里面的文件夹拷贝到/var/www/html里面去 1.安装之前先更新系统 sudo apt update 2.安装Apache2 sudo apt install apache2 3.安装 ...

  7. Python PEP 8 编码规范中文版

    原文链接:http://legacy.python.org/dev/peps/pep-0008/ 转发链接:https://blog.csdn.net/ratsniper/article/detail ...

  8. hdu 4027 Can you answer these queries?[线段树]

    题目 题意: 输入一个 :n  .(1<=n<<100000) 输入n个数    (num<2^63) 输入一个m :代表m个操作    (1<=m<<100 ...

  9. 物体检测,Error: maximum box coordinate value is too large

    使用ssd目标检测,出现error:maximum box coordinate value is larger than 1.100000: ] [1.325] 主要原因在于,用labelImg 标 ...

  10. 测试工具之Jmeter(各部件简单介绍)

    jmeter可以到官网下载: http://jakarta.apache.org/ 下载后解压即可使用,双击如下文件打开Jmeter界面: $JMETER_HOME\apache-jmeter-3.1 ...