import java.util.function.Consumer;
/**
* 切片工具类
*
* @author hexm
* @date 2020/7/1 11:13
*/
public class Slicer {
/**
* 实现类似Python的数组切片功能
*
* @param c 返回下标
* @param len 长度
* @param start 开始的index(包括)
* @param end 结束的index(不包括)
* @param step 步长,正值表示从左到右取值,负值表示从右到左取值,不能为0
*/
public static void slice(Consumer<Integer> c, int len, Integer start, Integer end, int step) {
if (len == 0 || step == 0) {
return;
}
if (step < 0) {
// 从右往左取值,而startIndex省略时,表示从端点开始,因此这里的端点是“终点”
if (start == null) {
start = len - 1;
} else if (start < 0) {
start += len;
}
if (end == null) {
end = -1;
} else if (end < 0) {
end += len;
}
} else {
// 从左往右取值,而startIndex省略时,表示从端点开始,因此这里的端点是“起点”
if (start == null) {
start = 0;
} else if (start < 0) {
start += len;
}
if (end == null) {
end = len;
} else if (end < 0) {
end += len;
}
}
// 判断是否可修正数值
if (start.equals(end) || start > end && step > 0 || start < end && step < 0) {
return;
}
//修正范围
if (start > len - 1) {
start = len - 1;
} else if (start < 0) {
start = 0;
}
if (end > len - 1) {
end = len;
} else if (end < 0) {
end = -1;
}
for (int i = start; step > 0 ? i < end : i > end; i += step) {
c.accept(i);
}
}
}
使用切片类切片字符串、集合、数组:
/**
* 实现类似Python的字符串切片功能
*
* @param str String
* @param start 开始的index(包括)
* @param end 结束的index(不包括)
* @param step 步长,正值表示从左到右取值,负值表示从右到左取值,不能为0
* @return 字符串
*/
public static String slice(CharSequence str, Integer start, Integer end, int step) {
if (str == null) {
return "";
}
StringBuilder sb = new StringBuilder();
Slicer.slice(i -> sb.append(str.charAt(i)), str.length(), start, end, step);
return sb.toString();
}
/**
* 实现类似Python的集合切片功能
*
* @param list 有序集合
* @param start 开始的index(包括)
* @param end 结束的index(不包括)
* @param step 步长,正值表示从左到右取值,负值表示从右到左取值,不能为0
* @return 新的集合
*/
public static <T> List<T> slice(List<T> list, Integer start, Integer end, int step) {
if (list == null) {
return null;
}
if (list.isEmpty()) {
return new ArrayList<>(0);
}
List<T> newList = new ArrayList<>();
Slicer.slice(i -> newList.add(list.get(i)), list.size(), start, end, step);
return newList;
}
/**
* 实现类似Python的数组切片功能
*
* @param array 数组
* @param start 开始的index(包括)
* @param end 结束的index(不包括)
* @param step 步长,正值表示从左到右取值,负值表示从右到左取值,不能为0
* @return 新的数组
*/
public static Object[] slice(Object array, Integer start, Integer end, int step) {
int len;
if (array == null) {
return null;
}
if ((len = Array.getLength(array)) == 0) {
return (Object[]) array;
}
List<Object> list = new ArrayList<>();
Slicer.slice(i -> list.add(Array.get(array, i)), len, start, end, step);
return list.toArray();
}
测试代码:
public static void main(String[] args) {
String str = "0123456789";
System.out.println("1:" + slice(str, 1, 6, 1));
System.out.println("2:" + slice(str, 1, 6, -1));
System.out.println("3:" + slice(str, 6, 2, 1));
System.out.println("4:" + slice(str, null, 6, 1));
System.out.println("5:" + slice(str, null, 6, -1));
System.out.println("6:" + slice(str, 6, null, 1));
System.out.println("7:" + slice(str, 6, null, -1));
System.out.println("8:" + slice(str, -1, -6, 1));
System.out.println("9:" + slice(str, -1, -6, -1));
System.out.println("10:" + slice(str, -6, -1, 1));
System.out.println("11:" + slice(str, null, -6, 1));
System.out.println("12:" + slice(str, -6, null, 1));
System.out.println("13:" + slice(str, -6, null, -1));
System.out.println("14:" + slice(str, 1, -6, 1));
System.out.println("15:" + slice(str, 1, -6, -1));
System.out.println("16:" + slice(str, -1, -6, 1));
System.out.println("17:" + slice(str, -1, 6, -1));
System.out.println("18:" + slice(str, null, null, 2));
System.out.println("19:" + slice(str, 0, -11, -1));
System.out.println("20:" + slice(str, 19, 11, 1));
System.out.println("21:" + slice(str, 9, 10, 1));
System.out.println("22:" + slice(str, -13, -11, -1));
}
完成输出内容:
1:12345
2:
3:
4:012345
5:987
6:6789
7:6543210
8:
9:98765
10:45678
11:0123
12:456789
13:43210
14:123
15:
16:
17:987
18:02468
19:0
20:
21:9
22:
Process finished with exit code 0
自己鼓捣的,写的不好可以指点下。