如何使用Java8功能基于参数从集合中获取项目

时间:2017-12-22 13:21:03

标签: java lambda foreach java-8 java-stream

我有一套以下项目

Set<String> formatLookup = new HashSet<>();
formatLookup.add("DHMdhm");
formatLookup.add("THMthm");
formatLookup.add("JHMjhm");

我正在传递一个字符串,如下所示

String filterVal = "THM";

现在我想检查过滤器值是否存在于集合的索引中(过滤器值顺序可能会有所不同,如THM,HTM,MHT等),我想从集合中返回该项目。以下是此代码以及它的工作原理。

private static String getStoredFilter(String filterVal) {
    String format = "DHMdhm";
    boolean found = false;
    Set<String> formatLookup = new HashSet<>();
    formatLookup.add("DHMdhm");
    formatLookup.add("THMthm");
    formatLookup.add("JHMjhm");
    Iterator<String> setIterator = formatLookup.iterator();
    while (setIterator.hasNext()) {
        String fmt = setIterator.next();
        for (int j = 0; j < filterVal.length(); j++) {
            if (!(fmt).contains(String.valueOf(filterVal.charAt(j)))) {
                found = false;
                break;
            } else {
            found = true;
            }
        }
        if (found) {
            return fmt;
        }
    }
    return null;
}

我想使用Java8功能。我是Java8的新手,我尝试使用流和foreach。但是,由于foreach无法返回值,因此我不确定如何完成此操作。

你可以帮我吗?

4 个答案:

答案 0 :(得分:1)

您可以通过简单地将两个键,键和输入带入规范的排列来处理排列,例如:只是对它们进行排序:

static String canonical(String s) {
    char[] c = s.toCharArray();
    Arrays.sort(c);
    return String.valueOf(c);
}

准备从规范键到指定字符串的地图

// do this only once
private static final Map<String,String> formatLookup
    = Stream.of("DHMdhm", "THMthm", "JHMjhm")
            .collect(Collectors.toMap(s -> canonical(s), Function.identity()));

和实际操作

private static String getStoredFilter(String filterVal) {
    String key = canonical(filterVal);

    // check whether there's an exact match
    String quickChecked = formatLookup.get(key);
    if(quickChecked!=null) return quickChecked;

    // search for substring matches
    return formatLookup.entrySet().stream()
        .filter(e -> e.getKey().contains(key))
        .map(Map.Entry::getValue)
        .findAny().orElse(null);
}

如果字符串可能包含重复字符并且您想要处理它,则只需更改canonical方法,例如

static String canonical(String s) {
    return s.codePoints().collect(BitSet::new, BitSet::set, BitSet::or).stream()
        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();
}

答案 1 :(得分:0)

这是如何做到的:

Set<String> formatLookup = new HashSet<>();
formatLookup.add("DHMdhm");
formatLookup.add("THMthm");
formatLookup.add("JHMjhm");
String filterVal = "THM";

String string = formatLookup.stream()
    .filter(s -> s.contains(filterVal))
    .findFirst()
    .orElse("noElement");
System.out.println(string);

您的输出将是:THMthm

如果您想要设置initail的索引,请使用以下代码:

Set<String> formatLookup = new HashSet<>();
formatLookup.add("DHMdhm");
formatLookup.add("THMthm");
formatLookup.add("JHMjhm");
String filterVal = "THM";
List<String> list = new ArrayList<String>(formatLookup);

String string = formatLookup.stream()
    .filter(s -> s.contains(filterVal))
    .findFirst()
    .orElse("noElement");
System.out.println(list.indexOf(string));

您的输出将是:1

如果要使用filterVal字符串的所有组合,请使用以下方法:

private static void permutation(String prefix, String s) {
    int n = s.length();
    if (n == 0) {
        System.out.println(prefix);
    } else {
        for (int i = 0; i < n; i++)
            permutation(prefix + s.charAt(i), s.substring(0, i) + s.substring(i + 1, n));
    }
}

调用此方法的输出如下:permutation("", filterVal);是:

THM
TMH
HTM
HMT
MTH
MHT

答案 2 :(得分:0)

如果您想使用Stream API,可以使用filter方法去掉您不想要的值,然后使用findAny()方法获取匹配的项目过滤谓词。

如果没有匹配项filter谓词findAny()将返回空可选

private static String getStoredFilter(String filterVal) {
    Set<String> formatLookup = new HashSet<>();
    formatLookup.add( "DHMdhm");
    formatLookup.add( "THMthm");
    formatLookup.add( "JHMjhm");

    Optional<String> matchedVal = formatLookup.stream()
            .filter(val -> val.contains(filterVal))
            // At this point only matched values will be available
            .findAny(); // Get the first one that matches

    // Return the matched value if there is any, otherwise returns null
    return matchedVal.orElse(null);
}

答案 3 :(得分:0)

获得匹配的第一个元素

    String e = formatLookup.stream().filter(s -> s.startsWith(filterVal)).findFirst().get();

收集所有匹配的

    List<String> elems = formatLookup.stream().filter(s -> s.startsWith(filterVal)).collect(Collectors.toList());

获取第一个匹配elem与Java9的位置(而Set使用List作为索引)

    long index = formatLookup.stream().dropWhile(s -> s.startsWith(filterVal)).count();