Java 字符串数组中的第一个唯一字符串

Java 字符串数组中的第一个唯一字符串,java,arrays,string,unique,Java,Arrays,String,Unique,给定一个字符串数组,如何找到数组中第一个唯一的字符串元素 public static String UniqueString(String[] s) { String str =""; for(int i=0;i<s.length;i++) { for(int j=i+1;j<s.length;j++) { System.out.println(s[i]+" "+s[j]);

给定一个字符串数组,如何找到数组中第一个唯一的字符串元素

public static String UniqueString(String[] s) {

    String str ="";

        for(int i=0;i<s.length;i++) {
            for(int j=i+1;j<s.length;j++) {
                System.out.println(s[i]+" "+s[j]);
                str = s[i];
                if(str==s[j]) {
                   break;
                }

                }if(!(str==s[i+1])){
                    return str;
                }

    }

    return str;
    }

因此,{Dog,Cat,Dog,Wolf,lion}的字符串数组将返回为Cat

如果您非常接近一个工作解决方案,您需要一个标志来指示您是否在s中再次找到该字符串,但不确定从何处获得名称。我们还将字符串与.equals进行比较,而不是==。方法名称以小写字母开头。大概

public static String uniqueString(String[] s) {
    for (int i = 0; i < s.length; i++) {
        boolean unique = true;
        for (int j = i + 1; j < s.length; j++) {
            if (s[j].equals(s[i])) {
                s[j] = s[s.length - 1]; // <-- handle bug, ensure that dupes aren't
                                        // found again.
                unique = false;
                break;
            }
        }
        if (unique) {
            return s[i];
        }
    }
    return "";
}

上述答案并非在所有情况下都适用。 例如{Dog,Dog,Cat}会返回Dog。问题是它没有检查整个阵列是否存在重复项

private static String getFirstUniqueString(String[] names) {
    for(int x=0;x<names.length;x++)
    {
        if(countOccurences(names[x],names) == 1 )
            return names[x];
    }
    return "No Unique Strings";
}

private static int countOccurences(String string, String[] names) 
{
    int count=0;
    for(int y = 0; y<names.length;y++)
    {
        if(names[y].equals(string))
        {
            count++;
            if(count >1 )
                return count;
        }
    }
    return count;
}
相反,也许会把它分成两部分。
一种是查找唯一字符串的方法,另一种是计算出现次数的方法。通过这种方法,我们可以精确计算整个数组中该单词被提及的次数。如果您只是想知道不止一个,并且希望节省运行时间,请取消对If语句的注释。

您的方法会随着列表的大小呈二次增长。有一种更好的方法本质上是线性的列表大小,即使用从字符串到出现次数的有序映射。使用一次遍历列表来构建映射,然后使用一次遍历映射来查找计数为1的第一个元素(如果有)。您可以使用来实现这一点

public static String uniqueString(String[] list) {
    Integer ZERO = 0; // to avoid repeated autoboxing below
    final LinkedHashMap<String, Integer> map = new LinkedHashMap<>(list.size());

    // build the map
    for (String s : list) {
        Integer count = map.getOrDefault(s, ZERO);
        map.put(s, count + 1);
    }

    // find the first unique entry. Note that set order is deterministic here.
    for (Set.Entry<String, Integer> entry : map.entrySet()) {
        if (entry.getValue() == 1) {
            return entry.getKey();
        }
    }

    // if we get this far, there was no unique string in the list
    return "";
}
但是,如果列表中有大量重复的字符串,则遍历
map可能需要更少的迭代。因此,我们不妨使用LinkedHashMap的新增功能,与HashMap相比,它的性能损失非常小。

也许还有另一种解决方案也可以用更java-8的方式解决您的问题:

使用映射记录重复字符串的计数,然后 从开始到结束直接遍历数组,然后 一旦字符串没有被复制,我们就可以得到它。 这可能是:

public static void main(String... args) {
    String[] arr = {"Dog", "Cat", "Dog", "Wolf", "lion"};
    Map<String, Long> stringCountMap = Arrays.stream(arr)
            .collect(Collectors.groupingBy(s -> s, Collectors.counting()));
    for (String s : arr) {
        if (stringCountMap.get(s) == 1) {
            System.out.println("The first non-duplicate string: " + s);
            break;
        }
    }
}
输出将始终为:

The first non-duplicate string: Cat
爪哇8

2年后更新:

我不知道为什么我会使用StringBuilder,因为我可以在一条语句中完成这一切:

public static String uniqueString(String[] s) {
    return Stream.of(s)
            .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))
            .entrySet()
            .stream()
            .filter(entry -> entry.getValue() == 1)
            .findFirst()
            .map(Map.Entry::getKey)
            .orElse(null);
}

使用地图。键是数组中的值,值是出现的次数。最后遍历它,并请求出现1次的第一个键…打印该键;不要使用==来比较Java中的字符串。请看:是的,这是有效的,但如果我可以问一下,如果布尔值高于第一个for循环,它为什么不起作用?@alo.fernando,因为一旦它设置为false,就不会将其设置为true。逻辑如下:我又找到这个字符串了吗?是真是假?@TedHop谢谢我不知道LinkedHashMap,我知道一种简单的方法来在地图中排序密钥集。这对多种情况非常有用。只是扩展了你的想法。。。List LISTSR=List.ofabc、xyz、abc、efg;字符串unique2=listStr.stream.collectCollectors.groupingByFunction.identity,LinkedHashMap::new,Collectors.counting.entrySet.stream.filtere->e.getValue==1.findFirst.OrelsMap.entry,0L.getKey;
The first non-duplicate string: Cat
public static String uniqueString(String[] s) {
    StringBuilder result = new StringBuilder();
    Stream.of(s)
            .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))
            .entrySet()
            .stream()
            .filter(entry -> entry.getValue() == 1)
            .findFirst()
            .ifPresent(entry -> result.append(entry.getKey()));
    return result.toString();
}
public static String uniqueString(String[] s) {
    return Stream.of(s)
            .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))
            .entrySet()
            .stream()
            .filter(entry -> entry.getValue() == 1)
            .findFirst()
            .map(Map.Entry::getKey)
            .orElse(null);
}