Java语法汇总-数据结构篇

Java数据结构汇总

接着上一篇《Java语法汇总-面向对象篇》,我们来学习汇总Java的数据结构相关的语法知识要点,包括字符串,集合,包装类型,泛型,Lambda表达式,枚举等等…的常用数据结构。这些都是Java编程所必须掌握的语法点,非常重要。

1. 字符串操作
  • 字符串常用方法
String s = "Hello";
System.out.println(s);
s = s.toUpperCase();
System.out.println(s);

// 比较
String s1 = "hello";
String s2 = "hello";
System.out.println(s1.equals(s2));

// 是否包含子串:
"Hello".contains("ll"); // true
// 搜索子串
"Hello".indexOf("l"); // 2
"Hello".lastIndexOf("l"); // 3
"Hello".startsWith("He"); // true
"Hello".endsWith("lo"); // true
// 提取子串
"Hello".substring(2); // "llo"
"Hello".substring(2, 4); // "ll"

// 去掉收尾空白字符串
"  \tHello\r\n ".trim(); // "Hello"

// 判断字符串为空
"".isEmpty(); // true,因为字符串长度为0
"  ".isEmpty(); // false,因为字符串长度不为0

// 替换子字符串
String s = "hello";
s.replace('l', 'w'); // "hewwo",所有字符'l'被替换为'w'
s.replace("ll", "~~"); // "he~~o",所有子串"ll"被替换为"~~"
String s = "A,,B;C ,D";
s.replaceAll("[\\,\\;\\s]+", ","); // "A,B,C,D"

// 分割字符串
String s = "A,B,C,D";
String[] ss = s.split("\\,"); // {"A", "B", "C", "D"}

// 拼接字符串
String[] arr = {"A", "B", "C"};
String s = String.join("***", arr); // "A***B***C"

// 类型转换
String.valueOf(123); // "123"
String.valueOf(45.67); // "45.67"
String.valueOf(true); // "true"
String.valueOf(new Object()); // 类似java.lang.Object@636be97c
int n1 = Integer.parseInt("123"); // 123
int n2 = Integer.parseInt("ff", 16); // 按十六进制转换,255
boolean b1 = Boolean.parseBoolean("true"); // true
boolean b2 = Boolean.parseBoolean("FALSE"); // false
Integer.getInteger("java.version"); // 版本号,11

char[] cs = "Hello".toCharArray(); // String -> char[]
String s = new String(cs); // char[] -> String
  • 字符串编码
try {

	byte[] b1 = "Hello".getBytes(); // 按系统默认编码转换,不推荐
	byte[] b2 = "Hello".getBytes("UTF-8"); // 按UTF-8编码转换
	byte[] b3 = "Hello".getBytes("GBK"); // 按GBK编码转换
	byte[] b4 = "Hello".getBytes(StandardCharsets.UTF_8); // 按UTF-8编码转换


	String s1 = new String(b1, "GBK"); // 按GBK转换
	String s2 = new String(b2, StandardCharsets.UTF_8); // 按UTF-8转换
}
catch (Exception ex)
{

}
  • StringBuilder
StringBuilder sb = new StringBuilder(1024);
for (int i = 0; i < 1000; i++) {
    sb.append(',');
    sb.append(i);
}
String s = sb.toString();
  • StringJoiner
String[] names = {"Bob", "Alice", "Grace"};
var sj = new StringJoiner(", ", "Hello ", "!");
for (String name : names) {
    sj.add(name);
}
System.out.println(sj.toString());
2. 包装类型

Java核心库为每种基本类型都提供了对应的包装类型

基本类型对应的引用类型
booleanjava.lang.Boolean
bytejava.lang.Byte
shortjava.lang.Short
intjava.lang.Integer
longjava.lang.Long
floatjava.lang.Float
doublejava.lang.Double
charjava.lang.Character
int i = 100;
// 通过new操作符创建Integer实例(不推荐使用,会有编译警告):
Integer n1 = new Integer(i);
// 通过静态方法valueOf(int)创建Integer实例:
Integer n2 = Integer.valueOf(i);
// 通过静态方法valueOf(String)创建Integer实例:
Integer n3 = Integer.valueOf("100");
System.out.println(n3.intValue());
Integer n = 100; // 编译器自动使用Integer.valueOf(int)
int x = n; // 编译器自动使用Integer.intValue()

// 进制转换
System.out.println(Integer.toString(100)); // "100",表示为10进制
System.out.println(Integer.toString(100, 36)); // "2s",表示为36进制
System.out.println(Integer.toHexString(100)); // "64",表示为16进制
System.out.println(Integer.toOctalString(100)); // "144",表示为8进制
System.out.println(Integer.toBinaryString(100)); // "1100100",表示为2进制

// boolean只有两个值true/false,其包装类型只需要引用Boolean提供的静态字段:
Boolean t = Boolean.TRUE;
Boolean f = Boolean.FALSE;
// int可表示的最大/最小值:
int max = Integer.MAX_VALUE; // 2147483647
int min = Integer.MIN_VALUE; // -2147483648
// long类型占用的bit和byte数量:
int sizeOfLong = Long.SIZE; // 64 (bits)
int bytesOfLong = Long.BYTES; // 8 (bytes)

// 向上转型为Number:
Number num = new Integer(999);
// 获取byte, int, long, float, double:
byte b = num.byteValue();
int n = num.intValue();
long ln = num.longValue();
float f = num.floatValue();
double d = num.doubleValue();

// 处理无符号整型
byte x = -1;
byte y = 127;
System.out.println(Byte.toUnsignedInt(x)); // 255
System.out.println(Byte.toUnsignedInt(y)); // 127
3. 枚举类型

enum Weekday {
    SUN, MON, TUE, WED, THU, FRI, SAT;
}
// 定义顺序
enum Weekday2 {
    MON(1), TUE(2), WED(3), THU(4), FRI(5), SAT(6), SUN(0);

    public final int dayValue;

    private Weekday2(int dayValue) {
        this.dayValue = dayValue;
    }
}

// 重写序号和显示字符串
enum Weekday3 {
    MON(1, "星期一"), TUE(2, "星期二"), WED(3, "星期三"), THU(4, "星期四"), FRI(5, "星期五"), SAT(6, "星期六"), SUN(0, "星期日");

    public final int dayValue;
    private final String chinese;

    private Weekday3(int dayValue, String chinese) {
        this.dayValue = dayValue;
        this.chinese = chinese;
    }

    @Override
    public String toString() {
        return this.chinese;
    }
}

Weekday day = Weekday.SUN;
if (day == Weekday.SAT || day == Weekday.SUN) {
    System.out.println("Work at home!");
} else {
    System.out.println("Work at office!");
}

if (day == Weekday.FRI) { // ok!
}
if (day.equals(Weekday.SUN)) { // ok, but more code!
}

// 枚举的使用
String s = Weekday.SUN.name(); // "SUN"
int n = Weekday.MON.ordinal(); // 1

Weekday3 day3 = Weekday3.SUN;
if (day3.dayValue == 6 || day3.dayValue == 0) {
    System.out.println("Today is " + day3 + ". Work at home!");
} else {
    System.out.println("Today is " + day3 + ". Work at office!");
}

try {
    Weekday day2 = Weekday.SUN;
    switch(day) {
        case MON:
        case TUE:
        case WED:
        case THU:
        case FRI:
            System.out.println("Today is " + day + ". Work at office!");
            break;
        case SAT:
        case SUN:
            System.out.println("Today is " + day + ". Work at home!");
            break;
        default:
            throw new RuntimeException("cannot process " + day);
    }

}
catch (Exception ex)
{

}
4. JavaBean

带有"属性"的类就叫做JavaBean

class Person {
    private String name;
    private int age;
    private boolean child;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    
	public boolean isChild(){
		return child;
	}
	public void setChild(boolean value){
		child=value;
	}
}

// 枚举一个JavaBean的所有属性
public static void main(String[] args) throws Exception {
    BeanInfo info = Introspector.getBeanInfo(Person.class);
    for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
        System.out.println(pd.getName());
        System.out.println("  " + pd.getReadMethod());
        System.out.println("  " + pd.getWriteMethod());
    }
}
5. 泛型使用
  • 集合泛型
List<Number> list = new ArrayList<Number>();
list.add(new Integer(123));
list.add(new Double(12.34));
Number first = list.get(0);
Number second = list.get(1);

//List<Number> list = new ArrayList<Number>();
// 可以省略后面的Number,编译器可以自动推断泛型类型:
List<Number> list = new ArrayList<>();
list.add(new Integer(123));
list.add(new Double(12.34));
Number first = list.get(0);
Number second = list.get(1);
  • 泛型接口
class Person implements Comparable<Person> {
    String name;
    int score;
    Person(String name, int score) {
        this.name = name;
        this.score = score;
    }
    public int compareTo(Person other) {
        return this.name.compareTo(other.name);
    }
    public String toString() {
        return this.name + "," + this.score;
    }
}

Person[] ps = new Person[] {
        new Person("Bob", 61),
        new Person("Alice", 88),
        new Person("Lily", 75),
};
Arrays.sort(ps);
System.out.println(Arrays.toString(ps));
6. 集合使用
  • List集合

实现方式有两种,区别如下:

使用ArrayListLinkedList
获取指定元素速度很快需要从头开始查找元素
添加元素到末尾速度很快速度很快
在指定位置添加/删除需要移动元素不需要移动元素
内存占用较大

通常情况下,我们总是优先使用ArrayList。

// 创建
List<String> list = new ArrayList<>();
list.add("apple"); // size=1
list.add("pear"); // size=2
list.add("apple"); // 允许重复添加元素,size=3
System.out.println(list.size());

// 遍历
for (int i=0; i<list.size(); i++) {
    String s = list.get(i);
    System.out.println(s);
}

for (String s : list) {
    System.out.println(s);
}

// 转换
String[] array = list.toArray(new String[3]);
for (String n : array) {
    System.out.println(n);
}

String[] array2 = list.toArray(new String[list.size()]);
List<String> array3 = Arrays.asList(array2);
System.out.println(array3.toString());

class Person {

    public String name;
    public int age;
    
    public Person(String name) {
        this.name = name;
    }
    // 如果调用List的contains()、indexOf()这些方法,需要实现equals()方法
    public boolean equals(Object o) {
        if (o instanceof Person) {
            Person p = (Person) o;
            return Objects.equals(this.name, p.name) && this.age == p.age;
        }
        return false;
    }
}

List<Person> lists = new ArrayList<Person>();
  • Map
class Student {
    public String name;
    public int score;
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
}

Student s = new Student("Xiao Ming", 99);
Map<String, Student> map = new HashMap<>();
map.put("Xiao Ming", s); // 将"Xiao Ming"和Student实例映射并关联
Student target = map.get("Xiao Ming"); // 通过key查找并返回映射的Student实例
System.out.println(target == s); // true,同一个实例
System.out.println(target.score); // 99
Student another = map.get("Bob"); // 通过另一个key查找
System.out.println(another); // 未找到返回null

Map<String, Integer> map = new HashMap<>();
map.put("apple", 123);
map.put("pear", 123); // ok

// 遍历
Map<String, Integer> map = new HashMap<>();
map.put("apple", 123);
map.put("pear", 456);
map.put("banana", 789);
for (String key : map.keySet()) {
    Integer value = map.get(key);
    System.out.println(key + " = " + value);
}

for (Map.Entry<String, Integer> entry : map.entrySet()) {
    String key = entry.getKey();
    Integer value = entry.getValue();
    System.out.println(key + " = " + value);
}

  • Collections工具类
// 创建空集合
List<String> list2 = Collections.emptyList();
// 创建单元素集合
List<String> list3 = Collections.singletonList("apple");
// 排序
Collections.sort(list2);

List<Integer> list = new ArrayList<>();
for (int i=0; i<10; i++) {
	list.add(i);
}
// 随机打乱顺序前:
System.out.println(list);
Collections.shuffle(list);
// 随机打乱顺序后:
System.out.println(list);

// 变为不可变集合:
List<String> immutable = Collections.unmodifiableList(list3);
7. Lambda与方法引用
class Person {
    String name;
    public Person(String name) {
        this.name = name;
    }
    public String toString() {
        return "Person:" + this.name;
    }
}

public class App 
{
    static int cmp(String s1, String s2) {
        return s1.compareTo(s2);
    }

    public static void main( String[] args )
    {
		 //Lambda表达式
         String[] array = new String[] { "Apple", "Orange", "Banana", "Lemon" };
         Arrays.sort(array, (s1, s2) -> {
             return s1.compareTo(s2);
         });
         System.out.println(String.join(", ", array));

         // 方法引用
         Arrays.sort(array, App::cmp);
         System.out.println(String.join(", ", array));

         Arrays.sort(array, String::compareTo);
         System.out.println(String.join(", ", array));

         List<String> names = List.of("Bob", "Alice", "Tim");
         List<Person> persons = names.stream().map(Person::new).collect(Collectors.toList());
         System.out.println(persons);

    }
}

8. Stream应用

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。


Stream<String> stream = Stream.of("A", "B", "C", "D");
// forEach()方法相当于内部循环调用,
// 可传入符合Consumer接口的void accept(T t)的方法引用:
stream.forEach(System.out::println);

Stream<String> stream1 = Arrays.stream(new String[] { "A", "B", "C" });
stream1.forEach(System.out::println);

// 将int[]数组变为IntStream:
IntStream is = Arrays.stream(new int[] { 1, 2, 3 });
// 将Stream<String>转换为LongStream:
LongStream ls =  Arrays.asList(new String[]{"1", "2", "3", "4"}).stream().mapToLong(Long::parseLong);

Stream<Integer> s = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> s2 = s.map(n -> n * n);

Arrays.asList(new String[]{"  Apple ", " pear ", " ORANGE", " BaNaNa "})
        .stream()
        .map(String::trim) // 去空格
        .map(String::toLowerCase) // 变小写
        .forEach(System.out::println); // 打印

IntStream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
        .filter(n -> n % 2 != 0)
        .forEach(System.out::println);

// 聚合运算
int sum = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).reduce(0, (acc, n) -> acc + n);
System.out.println(sum); // 45

int ss = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).reduce(1, (acc, n) -> acc * n);
System.out.println(ss); // 362880

// 过滤聚合
Stream<String> stream11 = Stream.of("Apple", "", null, "Pear", "  ", "Orange");
List<String> list = stream11.filter(s11 -> s11 != null && !s11.isEmpty()).collect(Collectors.toList());
System.out.println(list);

// 输出为List
List<String> list1 = Arrays.asList("Apple", "Banana", "Orange");
String[] array = list1.stream().toArray(String[]::new);
// 输出为map
Stream<String> stream2 = Stream.of("APPL:Apple", "MSFT:Microsoft");
Map<String, String> map = stream2
        .collect(Collectors.toMap(
                // 把元素s映射为key:
                s22 -> s22.substring(0, s22.indexOf(':')),
                // 把元素s映射为value:
                s22 -> s22.substring(s22.indexOf(':') + 1)));
System.out.println(map);

// 分组输出
List<String> list2 = Arrays.asList("Apple", "Banana", "Blackberry", "Coconut", "Avocado", "Cherry", "Apricots");
Map<String, List<String>> groups = list2.stream()
        .collect(Collectors.groupingBy(s22 -> s22.substring(0, 1), Collectors.toList()));
System.out.println(groups);

// 排序
List<String> list3 = Arrays.asList("Orange", "apple", "Banana")
        .stream()
        .sorted(String::compareToIgnoreCase)
        .collect(Collectors.toList());
// 去重
Arrays.asList("A", "B", "A", "C", "B", "D")
        .stream()
        .distinct()
        .collect(Collectors.toList()); // [A, B, C, D]

// 截取
Arrays.asList("A", "B", "C", "D", "E", "F")
        .stream()
        .skip(2) // 跳过A, B
        .limit(3) // 截取C, D, E
        .collect(Collectors.toList()); // [C, D, E]

// 合并
Stream<String> s111 = Arrays.asList("A", "B", "C").stream();
Stream<String> s222 = Arrays.asList("D", "E").stream();
Stream<String> s333 = Stream.concat(s111, s222);
System.out.println(s333.collect(Collectors.toList())); // [A, B, C, D, E]

Stream<List<Integer>> s4 = Stream.of(
        Arrays.asList(1, 2, 3),
        Arrays.asList(4, 5, 6),
        Arrays.asList(7, 8, 9));

Stream<Integer> i = s4.flatMap(list4 -> list4.stream());

//并行处理
Stream<String> s5 = Arrays.asList("A", "B", "C").stream();
String[] result = s5.parallel() // 变成一个可以并行处理的Stream
        .sorted() // 可以进行并行排序
        .toArray(String[]::new);


// 生成流
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered1 = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

// 遍历
s5.forEach(str -> {
    System.out.println("Hello, " + str);
});
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);


List<String> filtered2 = list2.stream().filter(str5 -> !str5.isEmpty()).collect(Collectors.toList());
System.out.println("筛选列表: " + filtered2);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("合并字符串: " + mergedString);

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();

System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值