美文网首页
Java 数据类型

Java 数据类型

作者: dawsonenjoy | 来源:发表于2018-12-09 00:25 被阅读0次

1、数组

数组属于引用类型数据,实质也是对象

动态初始化

先定义,然后new分配空间,接着再初始化赋值,举例:

int a[];
a = new int[3];
a[0] = 1;
a[1] = 2;
a[2] = 3;
静态初始化

定义的时候就赋值,举例:

int a[] = {1,2,3};
二维数组

定义举例:

int[][] a = {{1,2},{3,4}};
int[][] b = new int[2][];

在表格等情况下可能会用到,举例:

Object[] o1 = {"aaa", 18, "man"};
Object[] o2 = {"bbb", 22, "man"};
Object[] o3 = {"ccc", 20, "woman"};
Object[][] otable = new Object[3][];
otable[0] = o1;
otable[1] = o2;
otable[2] = o3;
for(Object[] o: otable)
    System.out.println(Arrays.toString(o));

结果:
[aaa, 18, man]
[bbb, 22, man]
[ccc, 20, woman]
数组复制

使用System.arraycopy(原数组, 起始位置, 拷贝到的数组, 起始位置, 拷贝长度),举例:

int[] a = {1,2,3,4,5};
int[] b = {0,0,0,0,0};
System.arraycopy(a, 1, b, 1, 3);
System.out.println(Arrays.toString(b));  //[0, 2, 3, 4, 0]

举例:

String[] s = {"1", "2", "3"};
String[] p = new String[s.length];
System.arraycopy(s, 0, p, 0, s.length);

2、String

不可变类型序列,在java.lang下的类,因此每个用""包起来的都是String类的一个实例

charAt(index)

返回字符串第index个字符,举例:

String s = "abcde";
System.out.print(s.charAt(2));  //c
length()

字符串长度

indexOf(str[,start])

返回字符串出现str的第一个位置(没有返回-1),第二个可选参数代表开始索引位置,举例:

String s = "abcde";
System.out.print(s.indexOf("c"));   //2
equals(str)

对于是否与str字符序列相等

equalsIgnoreCase(str)

忽略大小写后比较和str是否一样,举例:

String s = "abcde";
System.out.print(s.equalsIgnoreCase("ABCDE"));  //true
replace(old, new)

替换单个字符,举例:

String s = "abcde";
System.out.println(s.replace('a', 's'));    //bbcde
replaceAll(old, new)

替换字符串,举例:

String s = "abcde";
System.out.println(s.replaceAll("a", "bcd"));   //bcdbcde

里面也可以通过匹配正则表达式来替换,举例:

String a = "abc123de";
System.out.println(a.replaceAll("\\d+", "aaa"));    //abcaaade
startsWith(str)/endsWith(str)

是否以str开头/结尾

toUpperCase()/toLowerCase()

全部字符转大写/小写

substring(startIndex[,endIndex])

返回从startIndex到结尾的子序列,第二个参数可选,为到endIndex的子序列

trim()

去掉开头或者结尾空格后的字符串,相当于python的strip()

split(str)

按str分割字符串,举例:

String s = "abcde ";
System.out.print(s.split("a")[1]);  //bcde

实际上应该是按正则表达式来分割字符串,举例:

System.out.println(Arrays.toString("sd2a3s".split("\\d"))); //[sd, a, s]
toCharArray()

转成char字符数组,举例:

String a = "abcde";
for(char c: a.toCharArray())
    System.err.println(c);
matches()

匹配正则表达式,符合则返回true,否则返回false,举例:

String a = "abcde";
System.out.println(a.matches("[a-z]+"));    //true
getChars()/getBytes()

获得字符/字节数组

编码解码操作

使用getBytes(编码)进行编码(需要抛出异常),使用String(byte, 编码)进行解码,举例:

public static void main(String[] args) throws Exception{
    String s = "你好";
    byte[] b = s.getBytes("utf-8");
    System.out.println(new String(b, "utf-8")); //你好
}

要注意的是编码和解码时必须使用统一编码,否则会造成乱码,此时则需要再按其解码的编码进行编码,然后再按正确的编码进行解码,举例:

public static void main(String[] args) throws Exception{
    String s = "你好";
    byte[] b = s.getBytes("utf-8");
    String s1 = new String(b, "gbk");
    System.out.println(s1); //浣犲ソ
    byte[] b1 = s1.getBytes("gbk");
    String s2 = new String(b1, "utf-8");
    System.out.println(s2); //你好
}

3、容器API

Java提供了一个容器接口Collection(需要import java.util.*;),其下关系:

-Collection(接口)
    -Set(接口)
        -HashSet(类)
    -List(接口)
        -LinkedList(类)
        -ArrayList(类)
-Map(接口)
    -HashMap(类)

其中定义也有有讲究的,比如:

Collection a = new ArrayList();
ArrayList a = new ArrayList();

上面两者的区别:前者到时候如果想转LinkedList时可以直接转,而后者不行

3.1 Collection

其下的类都有以下的通用接口

add(Object)

添加元素(里面填的是对象),例如:a.add(new Integer(123))

size()

列表长度

remove(Object)

清除某个对象(里面也都是对象)

contains(Object)

是否包含该元素

iterator()

在这些数据类型下都有一个iterator接口,即迭代器,其定义了下面三个方法:

boolean hasNext();  //判断游标右边是否还有元素
Object next();  //返回游标右边元素,并将游标往右移一位
void remove();  //删除游标左边的元素

实现了上面的方法后就可以使用迭代器了,举例:

Collection c = new HashSet();
c.add(new String("1"));
c.add(new String("2"));
c.add(new String("3"));
Iterator i = c.iterator();
while(i.hashNext()){
String a = i.next();
}

上面可以用for语句实现:

Collection c = new HashSet();
c.add(new String("1"));
c.add(new String("2"));
c.add(new String("3"));
for(Object i: c)
System.out.println(i);
isEmpty()

是否为空

clear()

清空容器中所有元素

toArray()

转化成Object数组

containsAll(Collection)

是否包含该容器的所有元素

addAll(Collection)

添加容器的所有元素

removeAll(Collection)

删除本容器和该容器都包含的元素

retainAll(Collection)

取本容器和该容器中都包含的元素

3.2 List

列表里面可以存放各种类型的元素对象(注意是对象),有序,相比数组除了存放对象可以随意外,其不像数组大小固定,可以动态扩容,但是速度比数组慢。在java.util.Collections类下的List接口提供了常用方法如下

sort(List)

排序

reverse(List)

将原来的List倒过来,不是从大到小排序

shuffle(List)

随机排序

binarySearch(List, Object)

二分查找,第二个参数是要查找的对象,结果返回对象下标

copy(List1, List2)

将List2内容拷到List1

3.2.1 ArrayList

底层是数组实现的列表,查询效率高,增删效率低,线程不安全

3.2.2 LinkedList

和ArrayList相比,主要区别就是底层是链表实现的,因此查询效率低,增删效率高,线程也不安全

3.2.3 Vector

底层是数组实现的链表,相关的方法都加了同步检查(synchronized标记),因此线程安全,但同时效率也会低一些,使用方法和前两个差不多

3.2.4常用方法

add(index, Object)

重写了方法,在第几个位置插入元素

set(index, Object)

修改第几个位置元素的值

get(index)

获取第几个位置元素的值

remove(index)

重写了方法,删除第几个位置的元素

indexOf(Object)

获取某个元素的下标(第一个),没有就-1

lastIndexOf(Object)

获取某个元素的下标(最后一个)

3.3 Map

Map接口提供了键值对存放的数据类型接口

3.3.1 HashMap

通过键值对标识,底层是由ArrayList+LinkedList结合而成的hash表(总体由多行ArrayList组成,每行内由LinkedList组成)实现,对于该数据结果判断是否内容相等,一般不用equals,用hashCode来比较

3.3.2 TreeMap

底层是通过红黑二叉树来实现,效率一般低于HashMap,但是在排序Map的时候则会用到,即会根据Key值排序存储(底层继承了Comparable接口,实现的public int compareTo(Object obj){}方法是由Key排序)

3.3.3 HashTable

相比HashMap线程更安全,但是效率低,而且key和value不允许为空

3.3.4 常用方法
put(Object key, Object value)

添加键值对,本来添加的键值都必须是对象,但是在java1.5以后Map下支持自动将基础数据类型转成对象和对象转成基础数据(自动打包/解包机制),所以可以直接放基础数据,到时候会自动转成对象,举例:

Map m = new HashMap();
m.put("a", 1);  //自动转成String和Integer对象
int a = (Integer)m.get("a");
System.out.println(a)
get(Object key)

获取键值对

keySet()

获取所有键名,举例循环输出所有值:

Map<String, String> m = new HashMap<String, String>();
m.put("aaa", "bbb");
m.put("bbb", "ccc");
for (String s : m.keySet()) {
    System.out.println(m.get(s));
}
entrySet()

获取所有键值对的集合,返回的是Entry对象,举例:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class test {
    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<Integer, String>();
        map.put(1, "aaa");
        map.put(2, "bbb");
        Set<Entry<Integer, String>> s = map.entrySet();  //返回Entry对象
        for (Iterator<Entry<Integer, String>> iterator = s.iterator(); iterator
                .hasNext();) {
            Entry<Integer, String> entry = iterator.next();
            System.out.println(entry.getKey() + ":" + entry.getValue());
        }
    }
}

用迭代器比较繁琐,可以直接用for(x:XS)方式输出,举例:

public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<Integer, String>();
        map.put(1, "aaa");
        map.put(2, "bbb");
        for (Entry<Integer, String> m : map.entrySet()) {
            System.out.println(m.getKey() + ":" + m.getValue());
        }
    }
values()

获取所有值

remove(Object key)
containsKey(Object key)

是否包含键

containsValue(Object Value)

是否包含值

size()
putAll(Map)

添加所有键值对

clear()

清空键值对

3.4 Set

集合接口,无序(即无法用下标索引),不可重复

3.4.1 HashSet

底层是基于HashMap实现,相当于一个简化版HashMap,因此查询和增删效率都较高,使用方法可以参考Collection里的方法

3.4.2 TreeSet

底层是TreeMap实现的集合,所以结果会以从小到大排序

4、泛型

原来容器里的数据对象类型都是没有限制,因此基本都是接受Object,为了能够确定容器里存放的对象类型,引入了泛型,举例:

List<String> li = new ArrayList<String>();

这样所有的数据就都只能是String对象了,包括取数据时也可以使用泛型控制的迭代器,举例:

for(Iterator<String> it = li.interator(); it.hasNext(); )
{
String s = it.next();
System.out.println(s);
}

至于何时可以使用泛型,可以参考Api文档,当有<字符>标识则说明可以使用,比如Map<K, V>则说明键值都可以设置,所以就可以这样写:

Map<String, Integer> m = new hashMap<String, Integer>();
自定义泛型类

当自己写的类里假如需要一个泛型容器时,可以通过<字符>(一般用T/E/K/V/?,分别代表type/element/key/value/不确定类型,但其实啥都可以)来定义,此时该字符相当于一个形参,当实例化时设置泛型类后,该字符就是什么类,举例:

import java.util.Arrays;

public class test {
    public static void main(String[] args) {
        MyCollection<String> s = new MyCollection<String>(); // 设置了String的泛型,该对象里的T变成了String类
        s.set("aaa", 0); // 第一个参数只能传String
        System.out.println(s.toString());
    }
}
class MyCollection<T> { // 代表泛型类的形参
    Object[] o = new Object[5];
    public void set(T t, int index) { // T即传入的泛型类
        o[index] = t;
    }
    public String toString() {
        return Arrays.toString(this.o);
    }
}

相关文章

网友评论

      本文标题:Java 数据类型

      本文链接:https://www.haomeiwen.com/subject/weomcqtx.html