专栏名称: SegmentFault思否
SegmentFault (www.sf.gg)开发者社区,是中国年轻开发者喜爱的极客社区,我们为开发者提供最纯粹的技术交流和分享平台。
目录
相关文章推荐
程序员的那些事  ·  快!快!快!DeepSeek 满血版真是快 ·  昨天  
OSC开源社区  ·  RAG市场的2024:随需而变,从狂热到理性 ·  昨天  
程序员小灰  ·  清华大学《DeepSeek学习手册》(全5册) ·  3 天前  
OSC开源社区  ·  升级到Svelte ... ·  5 天前  
程序员的那些事  ·  成人玩偶 + ... ·  5 天前  
51好读  ›  专栏  ›  SegmentFault思否

30 秒收集有用的 Java8 代码片段

SegmentFault思否  · 公众号  · 程序员  · 2018-02-05 08:00

正文

文章作者:biezhi(https://github.com/biezhi) 文章地址:https://github.com/biezhi/30-seconds-of-java8

Array

chunk

将数组分割成特定大小的小数组。

  1. public static int[][] chunk(int[] numbers, int size) {

  2.    return IntStream.iterate(0, i -> i + size)

  3.            .limit((long) Math.ceil((double) numbers.length / size))

  4.            .mapToObj(cur -> Arrays.copyOfRange(numbers, cur, cur + size > numbers.length ? numbers.length : cur + size))

  5.            .toArray(int[][]::new);

  6. }

concat
  1. public static T[] concat(T[] first, T[] second) {

  2.    return Stream.concat(

  3.            Stream.of(first),

  4.            Stream.of(second)

  5.    ).toArray(i -> (T[]) Arrays.copyOf(new Object[0], i, first.getClass()));

  6. }

countOccurrences

计算数组中某个值出现的次数。

使用 Arrays.stream().filter().count() 计算等于指定值的值的总数。

  1. public static long countOccurrences(int[] numbers, int value) {

  2.    return Arrays.stream(numbers)

  3.            .filter(number -> number == value)

  4.            .count();

  5. }

deepFlatten

数组扁平化。

使用递归实现, Arrays.stream().flatMapToInt()

  1. public static int[] deepFlatten(Object[] input) {

  2.    return Arrays.stream(input)

  3.            .flatMapToInt(o -> {

  4.                if (o instanceof Object[]) {

  5.                    return Arrays.stream(deepFlatten((Object[]) o));

  6.                }

  7.                return IntStream.of((Integer) o);

  8.            }).toArray();

  9. }

difference

返回两个数组之间的差异。

从 b 中创建一个集合,然后在 a 上使用 Arrays.stream().filter() 只保留 b 中不包含的值。

  1. public static int[] difference(int[] first, int[] second) {

  2.    Set<Integer> set = Arrays.stream(second).boxed().collect(Collectors.toSet());

  3.    return Arrays.stream(first)

  4.            .filter(v -> !set.contains(v))

  5.            .toArray();

  6. }

differenceWith

从比较器函数不返回true的数组中筛选出所有值。

int的比较器是使用IntbinaryPerator函数来实现的。

使用 Arrays.stream().filter() Arrays.stream().noneMatch() 查找相应的值。

  1. public static int[] differenceWith(int[] first, int[] second, IntBinaryOperator comparator) {

  2.    return Arrays.stream(first)

  3.            .filter(a ->

  4.                    Arrays.stream(second)

  5.                            .noneMatch(b -> comparator.applyAsInt(a, b) == 0)

  6.            ).toArray();

  7. }

distinctValuesOfArray

返回数组的所有不同值。

使用 Arrays.stream().distinct() 去除所有重复的值。

  1. public static int[] distinctValuesOfArray(int[] elements) {

  2.    return Arrays.stream(elements).distinct().toArray();

  3. }

dropElements

移除数组中的元素,直到传递的函数返回true为止。返回数组中的其余元素。

使用数组循环遍历数组,将数组的第一个元素删除,直到函数返回的值为真为止。返回其余的元素。

  1. public static int[] dropElements(int[] elements, IntPredicate condition) {

  2.    while (elements.length > 0 && !condition.test(elements[0])) {

  3.        elements = Arrays.copyOfRange(elements, 1, elements.length);

  4.    }

  5.    return elements;

  6. }

dropRight

返回一个新数组,从右边移除n个元素。

检查n是否短于给定的数组,并使用 Array.copyOfRange() 以便对其进行相应的切片或返回一个空数组。

  1. public static int[] dropRight(int[] elements, int n) {

  2.    if (n < 0) {

  3.        throw new IllegalArgumentException("n is less than 0");

  4.    }

  5.    return n < elements.length

  6.            ? Arrays.copyOfRange(elements, 0, elements.length - n)

  7.            : new int[0];

  8. }

everyNth

返回数组中的每个第n个元素。

使用 IntStream.range().filter() 创建一个新数组,该数组包含给定数组的每个第n个元素。

  1. public static int[] everyNth(int[] elements, int nth) {

  2.     return IntStream.range(0, elements.length)

  3.             .filter(i -> i % nth == nth - 1)

  4.             .map(i -> elements[i])

  5.             .toArray();

  6. }

indexOf

查找数组中元素的索引,在不存在元素的情况下返回-1。

使用 IntStream.range().filter() 查找数组中元素的索引。

  1. public static int indexOf(int[] elements, int el) {

  2.    return IntStream.range(0, elements.length)

  3.            .filter(idx -> elements[idx] == el)

  4.            .findFirst()

  5.            .orElse(-1);

  6. }

lastIndexOf

查找数组中元素的最后索引,在不存在元素的情况下返回-1。

使用 IntStream.iterate().limit().filter() 查找数组中元素的索引。

  1. public static int lastIndexOf(int[] elements, int el) {

  2.    return IntStream.iterate(elements.length - 1, i -> i - 1)

  3.            .limit(elements.length)

  4.            .filter(idx -> elements[idx] == el)

  5.            .findFirst()

  6.            .orElse(-1);

  7. }

filterNonUnique

筛选出数组中的非唯一值。

对只包含唯一值的数组使用 Arrays.stream().filter()

  1. public static int[] filterNonUnique(int[] elements) {

  2.    return Arrays.stream(elements)

  3.            .filter(el -> indexOf(elements, el) == lastIndexOf(elements, el))

  4.            .toArray();

  5. }

flatten

使数组扁平。

使用 Arrays.stream().flatMapToInt().toArray() 创建一个新数组。

  1. public static int[] flatten(Object[] elements) {

  2.    return Arrays.stream(elements)

  3.            .flatMapToInt(el -> el instanceof int[]

  4.                    ? Arrays.stream((int[]) el)

  5.                    : IntStream.of((int) el)

  6.            ).toArray();

  7. }

flattenDepth

将数组压平到指定的深度。

  1. public static Object[] flattenDepth(Object[] elements, int depth) {

  2.    if (depth == 0) {

  3.        return elements;

  4.    }

  5.    return Arrays.stream(elements)

  6.            .flatMap(el -> el instanceof Object[]

  7.                    ? Arrays.stream(flattenDepth((Object[]) el, depth - 1))

  8.                    : Arrays.stream(new Object[]{el})

  9.            ).toArray();

  10. }

groupBy

根据给定函数对数组元素进行分组。

使用 Arrays.stream().collect(Collectors.groupingBy()) 分组。

  1. public static MapList> groupBy(T[] elements, Function func) {

  2.    return Arrays.stream(elements).collect(Collectors.groupingBy(func));

  3. }

initial

返回数组中除去最后一个的所有元素。

使用 Arrays.copyOfRange() 返回除最后一个之外的所有元素。

  1. public static T[] initial(T[] elements) {

  2.    return Arrays.copyOfRange(elements, 0, elements.length - 1);

  3. }

initializeArrayWithRange

初始化一个数组,该数组包含在指定范围内的数字,传入 start end

  1. public static int[] initializeArrayWithRange(int end, int start) {

  2.    return IntStream.rangeClosed(start, end).toArray();

  3. }

initializeArrayWithValues

使用指定的值初始化并填充数组。

  1. public static int[] initializeArrayWithValues(int n, int value) {

  2.    return IntStream.generate(() -> value).limit(n).toArray();

  3. }

intersection

返回两个数组中存在的元素列表。

从第二步创建一个集合,然后在 a 上使用 Arrays.stream().filter() 来保存包含在 b 中的值。

  1. public static int[] intersection(int[] first, int[] second) {

  2.    Set<Integer> set = Arrays.stream(second).boxed().collect(Collectors.toSet());

  3.    return Arrays.stream(first)

  4.            .filter(set::contains)

  5.            .toArray();

  6. }

isSorted

如果数组按升序排序,则返回 1 ,如果数组按降序排序,返回 -1 ,如果没有排序,则返回 0

计算前两个元素的排序 direction 。使用for循环对数组进行迭代,并对它们进行成对比较。如果 direction 发生变化,则返回 0 , 如果到达最后一个元素,则返回 direction

  1. public static extends Comparable super T>> int isSorted(T[] arr) {

  2.    final int direction = arr[0].compareTo(arr[1]) < 0 ? 1 : -1;

  3.    for (int i = 0; i < arr.length; i++) {

  4.        T val = arr[i];

  5.        if (i == arr.length - 1) return direction;

  6.        else if ((val.compareTo(arr[i + 1]) * direction > 0)) return 0;

  7.    }

  8.    return direction;

  9. }

join

将数组的所有元素连接到字符串中,并返回此字符串。

使用 IntStream.range 创建一个指定索引的数组。然后,使用 Stream.reduce 将元素组合成字符串。

  1. public static String join(T[] arr, String separator, String end) {

  2.    return IntStream.range(0, arr.length)

  3.            .mapToObj(i -> new SimpleEntry<>(i, arr[i]))

  4.            .reduce("", (acc, val) -> val.getKey() == arr.length - 2

  5.                    ? acc + val.getValue() + end

  6.                    : val.getKey() == arr.length - 1 ? acc + val.getValue() : acc + val.getValue() + separator, (fst, snd) -> fst);

  7. }

nthElement

返回数组的第n个元素。

Use Arrays.copyOfRange() 优先得到包含第n个元素的数组。

  1. public static T nthElement(T[] arr, int n) {

  2.    if (n > 0) {

  3.        return Arrays.copyOfRange(arr, n, arr.length)[0];

  4.    }

  5.    return Arrays.copyOfRange(arr, arr.length + n, arr.length)[0];

  6. }

pick

从对象中选择与给定键对应的键值对。

使用 Arrays.stream 过滤 arr 中存在的所有键。然后,使用 Collectors.toMap 将所有的key转换为Map。

  1. public static Map pick(Map obj, T[] arr) {

  2.    return Arrays.stream(arr)

  3.            .filter(obj::containsKey)

  4.            .collect(Collectors.toMap(k -> k, obj::get));

  5. }

reducedFilter

根据条件筛选对象数组,同时筛选出未指定的键。

使用 Arrays.stream().filter() 根据谓词 fn 过滤数组,以便返回条件为真的对象。

对于每个过滤的Map对象,创建一个新的Map,其中包含 keys 中的键。最后,将Map对象收集到一个数组中。

  1. public static Map<String, Object>[] reducedFilter(Map<String, Object>[] data, String[] keys, Predicate<Map<String, Object>> fn) {

  2.    return Arrays.stream(data)

  3.            .filter(fn)

  4.            .map(el -> Arrays.stream(keys).filter(el::containsKey)

  5.                    .collect( Collectors.toMap(Function.identity(), el::get)))

  6.            .toArray((IntFunction<Map<String, Object>[]>) Map[]::new);

  7. }

sample

从数组中返回一个随机元素。

使用 Math.Randoman() 生成一个随机数,然后将它乘以数组的 length ,然后使用 Math.floor() 获得一个最近的整数,该方法也适用于字符串。

  1. public static T sample(T[] arr) {

  2.    return arr[(int) Math.floor(Math.random() * arr.length)];

  3. }

sampleSize

array array 大小的唯一键获取 n 个随机元素。

根据Fisher-Yates算法,使用 Array.copyOfRange() 获得优先的 n 个元素。

  1. public static T[] sampleSize(T[] input, int n) {

  2.    T[] arr = Arrays.copyOf(input, input.length);

  3.    int length = arr.length;

  4.    int m = length;

  5.     while (m > 0) {

  6.        int i = (int) Math.floor(Math.random() * m--);

  7.        T tmp = arr[i];

  8.        arr[i] = arr[m];

  9.        arr[m] = tmp;

  10.    }

  11.    return Arrays.copyOfRange(arr, 0, n > length ? length : n);

  12. }

shuffle

将数组值的顺序随机化,返回一个新数组。

根据 Fisher-Yates 算法 重新排序数组的元素。

  1. public static T[] shuffle(T[] input) {

  2.    T[] arr = Arrays.copyOf(input, input.length);

  3.    int length = arr.length;

  4.    int m = length;

  5.    while (m > 0) {

  6.        int i = (int) Math.floor(Math.random() * m--);

  7.        T tmp = arr[i];

  8.        arr[i] = arr[m];

  9.        arr[m] = tmp;

  10.    }

  11.     return arr;

  12. }

similarity

返回出现在两个数组中的元素数组。

使用 Arrays.stream().filter() 移除,然后使用 Arrays.stream().anyMatch() 匹配 second 部分的值。

  1. public static T[] similarity(T[] first, T[] second) {

  2.    return Arrays.stream(first)

  3.            .filter(a -> Arrays.stream(second).anyMatch(b -> Objects.equals(a, b)))

  4.            // Make a new array of first's runtime type, but empty content:

  5.            .toArray(i -> (T[]) Arrays.copyOf(new Object[0], i, first.getClass()));

  6. }

sortedIndex

返回值应该插入到数组中的最低索引,以保持其排序顺序。

检查数组是否按降序(松散地)排序。 使用 IntStream.range().filter() 来找到元素应该被插入的合适的索引。

  1. public static extends Comparable super T>> int sortedIndex(T[] arr, T el) {

  2.    boolean isDescending = arr[0].compareTo(arr[arr.length - 1]) > 0;

  3.    return IntStream.range(0 , arr.length)

  4.            .filter(i -> isDescending ? el.compareTo(arr[i]) >= 0 : el.compareTo(arr[i]) <= 0)

  5.            .findFirst()

  6.            .orElse(arr.length);

  7. }

symmetricDifference

返回两个数组之间的对称差异。

从每个数组中创建一个 Set ,然后使用 Arrays.stream().filter() 来保持其他值不包含的值。最后,连接两个数组并创建一个新数组并返回。

  1. public static T[] symmetricDifference(T[] first, T[] second) {

  2.    Set sA = new HashSet<>(Arrays.asList(first));

  3.    Set sB = new HashSet<>(Arrays.asList(second));

  4.    return Stream.concat(

  5.            Arrays.stream(first).filter(a -> !sB.contains(a)),

  6.            Arrays.stream(second).filter(b -> !sA.contains(b))

  7.    ).toArray(i -> (T[]) Arrays.copyOf(new Object[0], i, first.getClass()));

  8. }

tail

返回数组中除第一个元素外的所有元素。

如果数组的长度大于1,则返回 Arrays.copyOfRange(1) ,否则返回整个数组。

  1. public static T[] tail(T[] arr) {

  2.    return arr.length > 1

  3.            ? Arrays.copyOfRange(arr, 1, arr.length)

  4.            : arr;

  5. }

take

返回一个从开头删除n个元素的数组。

  1. public static T[] take(T[] arr, int n) {

  2.    return Arrays.copyOfRange(arr, 0, n);

  3. }

takeRight

返回从末尾移除n个元素的数组。

使用 Arrays.copyOfRange() 用从末尾取来的 N 个元素来创建一个数组。

  1. public static T[] takeRight(T[] arr, int n) {

  2.    return Arrays.copyOfRange(arr, arr.length - n, arr.length);

  3. }

union

返回两个数组中任何一个中存在的每个元素一次。

使用 a b 的所有值创建一个 Set ,并将其转换为数组。

  1. public static T[] union(T[] first, T[] second) {

  2.     Set set = new HashSet<>(Arrays.asList(first));

  3.    set.addAll(Arrays.asList(second));

  4.    return set.toArray((T[]) Arrays.copyOf(new Object[0], 0, first.getClass()));

  5. }

without

筛选出具有指定值之一的数组的元素。

使用 Arrays.strean().filter() 创建一个数组,排除(使用 !Arrays.asList(elements).contains() )所有命中的值。

  1. public static T[] without(T[] arr, T... elements) {

  2.    List excludeElements = Arrays.asList(elements);

  3.    return Arrays.stream(arr)

  4.            .filter(el -> !excludeElements.contains(el))

  5.            .toArray(i -> (T[]) Arrays.copyOf(new Object[0], i, arr.getClass()));

  6. }

zip

根据原始数组中的位置创建元素数组。

  1. public static List<Object[]> zip(Object []... arrays) {

  2.    OptionalInt max = Arrays.stream(arrays).mapToInt(arr -> arr.length).max();

  3.    return IntStream.range(0, max.getAsInt())

  4.            .mapToObj(i -> Arrays.stream(arrays)

  5.                    .map(arr -> i < arr.length ? arr[i] : null)

  6.                    .toArray())

  7.            .collect(Collectors.toList());

  8. }

zipObject

给定有效的属性标识符数组和值数组,返回将属性与值关联的对象。

  1. public static Map<String, Object> zipObject(String[] props, Object[] values) {

  2.    return IntStream.range(0, props.length)

  3.            .mapToObj(i -> new SimpleEntry<>(props[i], i < values.length ? values[i] : null))

  4.            .collect(

  5.                    HashMap::new, (m, v) -> m.put(v.getKey(), v.getValue()), HashMap::putAll);

  6. }

Maths

average

返回两个或两个以上数字的平均值。

  1. public static double average(int[] arr) {

  2.    return IntStream.of(arr)

  3.            .average()

  4.            .orElseThrow(() -> new IllegalArgumentException("Array is empty"));

  5. }

gcd

计算一系列数字的最大公约数(gcd)。

使用 Arrays.stream().reduce() 和 GCD(使用递归公式)计算一组数字的最大公约数。

  1. public static OptionalInt gcd(int[] numbers) {

  2.    return Arrays.stream(numbers)

  3.            .reduce((a, b) -> gcd(a, b));

  4. }

  5. private static int gcd(int a, int b) {

  6.    if (b == 0) {

  7.        return a;

  8.    }

  9.    return gcd(b, a % b);

  10. }

lcm

计算数字数组的最低公共倍数(LCM)。

使用 Arrays.stream().reduce() 和 LCM公式(使用递归)来计算数字数组的最低公共倍数。

  1. public static OptionalInt lcm(int[] numbers) {

  2.    IntBinaryOperator lcm = (x, y) -> (x * y) / gcd(x, y);

  3.    return Arrays.stream(numbers)

  4.            .reduce((a, b) -> lcm.applyAsInt(a, b));

  5. }

  6. private static int gcd(int a, int b) {

  7.    if (b == 0) {

  8.        return a;

  9.    }

  10.    return gcd(b, a % b);

  11. }

findNextPositivePowerOfTwo

查找大于或等于该值的下一个幂。

该方法使用左移运算符将1与右侧的值位移。右侧使用 Integer.numberOfLeadingZeros 方法。

001<<2 would be 100 . 100 in decimal is equal to 4 .

Integer.numberOfLeadingZeros 给出了数值前导零的数目。例如,调用 Integer.numberOfLeadingZeros(3) 将赋值为30。

这是因为3在二进制中表示为 11 。由于整数有32位,所以有30位有0位。左移运算符的右边变为 32-30=2

左移1,即 001<<2 将是 100 ,十进制中的 100 等于 4

  1. public static int findNextPositivePowerOfTwo(int value) {

  2.    return 1 << (32 - Integer.numberOfLeadingZeros(value - 1));

  3. }

isEven

检查数字是否是偶数。

这个方法使用按位运算符, 0b1 是1的二进制表示。

因为Java 7可以通过用 0b 0B 作为前缀来编写二进制文字。

数字为偶数时, 运算符将返回0。 例如, IsEven(4) 会导致 100 & 001 的结果将是 000

  1. public static boolean isEven(final int value) {

  2.    return (value & 0b1) == 0;

  3. }

isPowerOfTwo

检查一个值是2的正幂。

为了理解它是如何工作的,让我们假设我们调用了 IsPowerOfTwo(4)

当值大于0时,将评估 && 运算符的右侧。

(~value+1) 的结果等于值本身, ~100+001 => 011+001 => 100

(value&value) 的结果是value, 100 & 100 => 100 .。

当值等于值时,这将把值表达为真值。

  1. public static boolean isPowerOfTwo(final int value) {

  2.    return value > 0 && ((value & (~value + 1)) == value);

  3. }

generateRandomInt

生成一个介于 Integer.MIN_VALUE Integer.MAX_VALUE 之间的随机数。

  1. public static int generateRandomInt() {

  2.    return ThreadLocalRandom.current().nextInt();

  3. }

String

anagrams

生成一个字符串的所有字符(包含重复)。

  1. public static List<String> anagrams(String input) {

  2.    if (input.length() <= 2) {

  3.        return input.length() == 2

  4.                ? Arrays.asList(input, input.substring(1) + input.substring(0, 1))

  5.                : Collections.singletonList(input);

  6.    }

  7.    return IntStream.range(0, input.length())

  8.            .mapToObj(i -> new SimpleEntry<>(i, input.substring(i, i + 1)))

  9.            .flatMap(entry ->

  10.                    anagrams(input.substring(0, entry.getKey()) + input.substring(entry.getKey() + 1))

  11.                            .stream()

  12.                            .map(s -> entry.getValue() + s))

  13.            .collect(Collectors.toList());

  14. }

byteSize

以字节为单位返回字符串的长度。

  1. public static int byteSize(String input) {

  2.     return input.getBytes().length;

  3. }

capitalize

将字符串首字母大写。

  1. public static String capitalize(String input, boolean lowerRest) {

  2.    return input.substring(0, 1).toUpperCase() +

  3.            (lowerRest

  4.                    ? input.substring(1, input.length()).toLowerCase()

  5.                    : input.substring(1, input.length()));

  6. }

capitalizeEveryWord

将字符串中每个单词的首字母大写。

  1. public static String capitalizeEveryWord(final String input) {

  2.    return Pattern.compile("\\b(?=\\w)").splitAsStream(input)

  3.            .map(w -> capitalize(w, false))

  4.            .collect(Collectors.joining());

  5. }

countVowels

在提供的字符串中返回元音的个数。

  1. public static int countVowels(String input) {

  2.    return input.replaceAll("#footnote-aeiouAEIOU">[aeiouAEIOU]", "").length();

  3. }

escapeRegExp

转义要在正则表达式中使用的字符串。

  1. public static String escapeRegExp(String input) {

  2.    return Pattern.quote(input);

  3. }

fromCamelCase

从驼峰式转换字符串。

  1. public static String fromCamelCase(String input, String separator) {

  2.    return input

  3.            .replaceAll("([a-z\\d])([A-Z])", "$1" + separator + "$2")

  4.            .toLowerCase();

  5. }

isAbsoluteUrl

如果给定的字符串是绝对URL,则返回 true ,否则返回 false

  1. public static boolean isAbsoluteUrl(String url) {

  2.    return Pattern .compile("^[a-z][a-z0-9+.-]*:").matcher(url).find();

  3. }

isLowerCase

检查字符串是否为小写。

  1. public static boolean isLowerCase(String input) {

  2.    return Objects.equals(input, input.toLowerCase());

  3. }

isUpperCase

检查字符串是否为大写。

  1. public static boolean isUpperCase(String input) {

  2.    return Objects.equals(input, input.toUpperCase());

  3. }

isPalindrome

判断一个字符串是否回文。

  1. public static boolean isPalindrome(String input) {

  2.    String s = input.toLowerCase().replaceAll("[\\W_]", "");

  3.    return Objects.equals(

  4.            s,

  5.            new StringBuilder(s).reverse().toString()

  6.    );

  7. }

isNumeric

检查字符串是否为数字。

  1. public static boolean isNumeric(final String input) {

  2.    return IntStream.range(0, input.length())

  3.            .allMatch(i -> Character.isDigit(input.charAt(i)));

  4. }

mask

用指定的掩码字符替换除最后 num 个字符以外的所有字符。

  1. public static String mask(String input, int num, String mask) {

  2.    







请到「今天看啥」查看全文