Java名字生成器

By | 9月 5, 2018

有时需要自动生成名字,例如Custom1, Custom2, Custom3…..这里的名字有个特点:固定的字符串+数字。为了方便生成“任意字符串+数字”的名字,我写了下面的工具类。

使用方法

1
2
3
4
5
List<String> existingNames = Lists.newArrayList("Trump", "NewName1",
      "NewName4", "KFC" ,"NewName5", "Custom Name");
 NameGenerator nameGenerator = new NameGenerator("NewName");
 // nextName is "NewName6".
 String nextName = nameGenerator.next(existingNames);

源代码

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import java.util.List;
import java.util.Objects;
import java.util.OptionalLong;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import com.google.common.base.Strings;
import com.google.common.primitives.Longs;
 
/**
 * It is used to generate a contiguous increment name. It finds the max number of existing
 * name pattern and increase the number by one to create a new name. For example name
 * pattern is "NewName" plus number and existing names are "NewName1, NewName4, NewName5",
 * then next new name is "NewName6".
 *
 * <p><b>Usage:</b>
 *
 * <pre>{@code
 * List<String> existingNames = Lists.newArrayList("Trump", "NewName1",
 *      "NewName4", "KFC" ,"NewName5", "Custom Name");
 * NameGenerator nameGenerator = new NameGenerator("NewName");
 * // nextName is "NewName6".
 * String nextName = nameGenerator.next(existingNames);
 * }</pre>
 *
 * @author alzhang
 */
public class NameGenerator {
 
  private long startFrom = 1;
  private String namePattern = "New";
 
  /**
   * Create a NameGenerator.
   *
   * @param namePattern the name pattern.
   */
  public NameGenerator(String namePattern) {
    if (!Strings.isNullOrEmpty(namePattern)) {
      this.namePattern = namePattern;
    }
  }
 
  /**
   * Find the next name according to given existing names. Not matched name will be simply filtered out.
   *
   * @param existingNames a list of existing names.
   * @return a string of next name.
   */
  public String next(List<String> existingNames) {
    if (existingNames == null) {
      return createName(startFrom);
    }
 
    Pattern pattern = Pattern.compile(String.format("(%s{1})\\s*(\\d*)", namePattern));
    OptionalLong maxNumOpt = existingNames.stream()
        .filter(Objects::nonNull)
        .map(str -> {
          Matcher matcher = pattern.matcher(str);
          return matcher.find() ? Longs.tryParse(matcher.group(2)) : null;
        }).filter(Objects::nonNull)
        .mapToLong(Long::longValue)
        .max();
 
    long nextNum = maxNumOpt.isPresent() ? maxNumOpt.getAsLong() + 1 : startFrom;
    return createName(nextNum);
  }
 
  private String createName(long index) {
    return String.format("%s%d", namePattern, index);
  }
 
}