Is there any helper method or utility that actually gives me union of two strings.
For instance, if i have two strings as below:
String s1 = "Isabella,tom,hardy";
String s2 = "Isabella,tom,hardy,victor,smith";
I'm looking for a solution which will take above two strings as input and outputs the result as below:
General syntax: s1.{method/utility}(s2);
output : Isabella,tom,hardy,victor,smith
First, there is no method or utility provided by JDK to address the problem so straight forward.
Second, just for this simple utility importing a 3rd party jar or dependency is not a wise choice.
In this case its always a wise choice to write your own method of purpose.
public static String mergeString(String s1, String s2) {
//check for null as the method doesnt fall in NPE
if(s1 == null || s2 == null) {
return null;
}
//split the given String to some list
List<String> s1List = Arrays.asList(s1.split(","));
List<String> s2List = Arrays.asList(s2.split(","));
//get a Set and add the list items to it. LinkedHashSet
//is used to maintain the given order.
Set<String> stringSet = new LinkedHashSet<>(s1List);
stringSet.addAll(s2List);
//Then join them using java 8 provided Utility
return String.join(",", stringSet);
}
NB: as you mentioned in the comments you may need this type of utility only once in your project. But despite, this logic should be separated from out of your business method. This will make your code more clean and readable.
You can use org.springframework.util.StringUtils
Add a maven dependency spring-core:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>
Use StringUtils:
public static void main(String[] args) {
String s1 = "Isabella,tom,hardy";
String s2 = "Isabella,tom,hardy,victor,smith";
String[] outputArr=StringUtils.mergeStringArrays(s1.split(","),s2.split(","));
String output=StringUtils.arrayToCommaDelimitedString(outputArr);
System.out.println(output);
}
Output:
Isabella,tom,hardy,victor,smith
public void unionString(String s1, String s2){
String[] s1Ar = s1.split(",");
String[] s2Ar = s2.split(",");
HashSet<String> set = new HashSet<String>();
for(int i=0;i<s1Ar.length;i++){
set.add(s1Ar[i]);
}
for(int i=0;i<s2Ar.length;i++){
set.add(s2Ar[i]);
}
Iterator<String> it = set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
Here's a method that will do the union of two strings. You can also pass it a boolean flag to dictate case sensitivity.
public static String union (String s1, String s2, boolean caseInsensitive)
{
// if either string is null, union is the other string
if (s1 == null)
return s2;
if (s2 == null)
return s1;
// use linked set to keep ordering
Set<String> unique = new LinkedHashSet<>();
// put all words from string 1 into the set
for (String word : s1.split(","))
{
word = word.trim(); // remove surrounding space on word
if (caseInsensitive)
{
word = word.toLowerCase();
}
unique.add(word);
}
// put all words from string 2 into the set
for (String word : s2.split(","))
{
word = word.trim(); // remove surrounding space on word
if (caseInsensitive)
{
word = word.toLowerCase();
}
unique.add(word);
}
// get back the format of comma delimiter for the union
String ret = unique.toString().replaceAll("[\\[\\] ]", "");
return ret;
}
Usage:
public static void main(String args[])
{
String s1 = "Isabella,tom,hardy";
String s2 = "Isabella,tom,hardy,victor,smith";
String union = union(s1, s2, false);
System.out.println(union);
}
Outputs:
Isabella,tom,hardy,victor,smith
You Can Use LinkedHashSet which maintains the insertion Order to get desired output.Below is my code:
public class UnionJava {
static LinkedHashSet<String> hashSetString = new LinkedHashSet<>();
static String s1 = "Isabella,tom,hardy"; static String s2 = "Isabella,tom,hardy,victor,smith";
public static void main(String args[]){
String[] set1 = s1.split(","); String[] set2 = s2.split(",");
for(int i=0; i< set1.length;i++){
hashSetString.add(set1[i]);
}
for(int i=0;i<set2.length;i++){
hashSetString.add(set2[i]);
}
int j=0;
for(Iterator i = hashSetString.iterator(); i.hasNext();){
if(j==0){
System.out.print(i.next());
j++;
}else{
System.out.print(","+i.next());
}
}
}
}
A short version with no sanity checks using LinkedHashSet.
public void printUnion() {
String s1 = "Isabella,tom,hardy";
String s2 = "Isabella,tom,hardy,victor,smith";
Set<String>mySet = new LinkedHashSet<>();
mySet.addAll(Arrays.asList(s1.split(",")));
mySet.addAll(Arrays.asList(s2.split(",")));
mySet.stream().forEach(System.out::println);
}
With the java api, you might try :
public class StringTest {
private String string1 ="";
private String string2 ="";
private List<String> array1 = new ArrayList<String>();
private List<String> array2 = new ArrayList<String>();
private String[] stringa1;
private String[] stringa2;
private int output3 = 0;
private int output4 = 0;
public static void main(String[] args) {
new StringTest().startApp();
}
private void startApp() {
string1 = "Isabella,tom,hardy";
stringa1 = string1.split("\\s+"); //array to split
string2 = "Isabella,tom,hardy,victor,smith";
stringa2 = string2.split("\\s+");
for(int o = 0; o<stringa1.length; o++) {
array1.add(stringa1[o]); //adding to arraylist
}
for(int o = 0; o<stringa2.length; o++) {
array2.add(stringa2[o]);
}
for(int outP = 0; outP<array2.size()+array1.size(); outP++) {
for(output4 = 0; output4<array2.size(); output4++) { //iterating and removing double elements
for(output3 = 0; output3<array1.size(); output3++) {
if(array1.size() > array2.size() && array2.get(output4).equalsIgnoreCase(array1.get(output3))) {
array1.remove(array1.get(output3));
}
if(array1.size() < array2.size() && array2.get(output4).equalsIgnoreCase(array1.get(output3))) {
array2.remove(array2.get(output4));
}
}
}
}
array1.addAll(array2); //merging the lists
for(String outPres1 : array1) {
result += " " + outPres1;
}
System.out.println("This is the output: " + result);
}
String s1 = "Isabella,tom,hardy";
String s2 = "Isabella,tom,hardy,victor,smith";
Set<String> result = new TreeSet<String>();
result.addAll(Arrays.asList(s1.split((","))));
result.addAll(Arrays.asList(s2.split((","))));
System.out.println(result);
Well, someone's got to provide a streams solution:
Stream.of(s1, s2)
.flatMap(Pattern.compile(",")::splitAsStream)
.distinct()
.collect(Collectors.joining(","))
Related
I am trying to remove elements from String A using an array of String B.
My logic is to convert the string A to an array and then check if A contains the same elements as B and write that data to an empty String, but it doesn't work if B has two or more elements.
Can you tell me what I'm doing wrong?
class Test {
public static void main(String[] args) {
WordDeleter wordDeleter = new WordDeleter();
// Hello
System.out.println(wordDeleter.remove("Hello Java", new String[] { "Java" }));
// The Athens in
System.out.println(wordDeleter.remove("The Athens is in Greece", new String[] { "is", "Greece" }));
// This cat
System.out.println(wordDeleter.remove("This is cat", new String[] { "is" }));
}
}
class WordDeleter {
public String remove(String phrase, String[] words) {
String[] arrayPhrase = phrase.split(" ");
String result = "";
for (int i = 0; i < arrayPhrase.length; i++) {
for (int j = 0; j < words.length; j++) {
if (!arrayPhrase[i].equalsIgnoreCase(words[j]))
result += arrayPhrase[i] + " ";
}
}
return result.trim();
}
}
Output is:
Hello
The The Athens Athens is in in Greece
This cat
You're close but you need to use the helpful .contains() method. This should work for the multi-length set of words. Your nested for loop checked for both words, thus the copying. Also the not-allowed words were only written once, so it infact "worked" but not the way you intended.
class Test {
public static void main(String[] args) {
WordDeleter wordDeleter = new WordDeleter();
// Hello
System.out.println(wordDeleter.remove("Hello Java", new String[] { "Java" }));
// The Athens in
System.out.println(wordDeleter.remove("The Athens is in Greece", new String[] { "is", "Greece" }));
// This cat
System.out.println(wordDeleter.remove("This is cat", new String[] { "is" }));
}
}
class WordDeleter {
public String remove(String phrase, String[] wordsArray) {
List<String> words = Arrays.asList(wordsArray);
String[] arrayPhrase = phrase.split(" ");
String result = "";
for (int i = 0; i < arrayPhrase.length; i++) {
// If the word is not contained in the not allowed array
if(!words.contains(arrayPhrase[i])){
result += arrayPhrase[i] + " ";
}
}
return result.trim();
}
}
Another thing you can do to make it better is use StringBuilder.
Instead of String result = "", use StringBuilder result = new StringBuilder(). And instead of result +=arrayPhrase[i] + " "; use result.append(arrayPhrase[i] + " "); as so:
class Test {
public static void main(String[] args) {
WordDeleter wordDeleter = new WordDeleter();
// Hello
System.out.println(wordDeleter.remove("Hello Java", new String[] { "Java" }));
// The Athens in
System.out.println(wordDeleter.remove("The Athens is in Greece", new String[] { "is", "Greece" }));
// This cat
System.out.println(wordDeleter.remove("This is cat", new String[] { "is" }));
}
}
class WordDeleter {
public String remove(String phrase, String[] words) {
String[] arrayPhrase = phrase.split(" ");
StringBuilder result = new StringBuilder();
for (int i = 0; i < arrayPhrase.length; i++) {
// If the word is not contained in the not allowed array
if(!words.contains(arrayPhrase[i])){
result.append(arrayPhrase[i] + " ");
}
}
return result.toString().trim();
}
}
The most efficient way to remove all occurrences of strings contained in the given array from the given string is to generate a HashSet from the given array and check for every word in the given string, whether it's present in the set or not.
To avoid overheads of string concatenation, we can use StringJoiner.
That's how it can be implemented.
public static String remove(String phrase, String[] words) {
String[] arrayPhrase = phrase.split(" ");
Set<String> wordsToRemove = Arrays.stream(words).collect(Collectors.toSet());
StringJoiner result = new StringJoiner(" ");
for (String word: arrayPhrase) {
if (!wordsToRemove.contains(word)) {
result.add(word);
}
}
return result.toString();
}
And that's how it can be implemented with streams using collector joining():
public static String remove(String phrase, String[] words) {
Set<String> wordsToRemove = Arrays.stream(words).collect(Collectors.toSet());
return Arrays.stream(phrase.split(" "))
.filter(word -> !wordsToRemove.contains(word))
.collect(Collectors.joining(" "));
}
A link to Online Demo
I have name String[] let suppose "Raj Kumar". Then the condition is that I want to get "R" from Raj and "K" from "Kumar" and if the text is "Raj" then I have to get "Ra" from "Raj". How do I do that below is the code I want to modify.
code:-
public static final String[] titles = new String[]{"Raj", "Niraj Kumar"};
for(int i = 0;i<titles.length;i++){
char firstChar = titles[i].charAt(0);
}
You this method
public String getShortName(String name){
String[] token=name.split(" ");
if(token.length>1){
String value="";
for(int i=0;i<token.length;i++){
value+=token[i].substring(0,1);
}
return value;
}else{
return token[0].length()>1?token[0].substring(0,2):token[0];
}
}
I have tested it, For array of names use this method in for loop
First, create this method to process each individual string in the array:
private static String processString(String string) {
String[] words = string.split(" ");
if (words.length == 1) {
return words[0].substring(0, 2);
} else {
return Arrays.stream(words).map(x -> Character.toString(x.charAt(0))).collect(Collectors.joining());
}
}
And then, stream the array and map each item using the method:
List<String> mapped = Arrays.stream(titles)
.map(YourEnclosingClass::processString)
.collect(Collectors.toList());
You can then print the values out like this:
mapped.forEach(System.out::println);
You can try like this :
public static final String[] titles = new String[]{"Raj", "Niraj Kumar"};
for(int i = 0;i<titles.length;i++){
if(titles[i].contains(" ")){
char firstChar = titles[i].charAt(0) + titles[i].split(" ")[1].charAt(0);
}else{
char firstChar = titles[i].charAt(0) + titles[i].charAt(1);
}
}
final String[] titles = new String[]{"Raj", "Niraj Kumar"};
for (int i = 0;i<titles.length;i++){
String shortChar;
String[] nameSplit = titles[i].split("\\s+");
if(nameSplit.length == 1) {
shortChar = nameSplit[0].substring(0,2);
} else {
shortChar = nameSplit[0].substring(0,1) + nameSplit[1].substring(0,1);
}
}
Here you'll get Ra and NK as output (Hoping that the name contains first and second name only)
Here is another way using stream API:
Arrays.stream(titles)
.map(title -> title.contains(" ") ?
Arrays.stream(title.split(" "))
.reduce("", (a, b) -> a + b.charAt(0)) :
title.substring(0, 2))
.forEach(result -> {
// do with result
});
I am working on my own personal app for minecraft. I would forget what recipe I need, and I would just search, and have it display the recipe.
Now, I have the list and search function with it being alphabetical. Now I am manually adding images, and everything else I need. BUT I think it would be more efficient if I had a array string like this
String test1[] = { "diamond", "Iron", "Leather" };
String test2[] = { "Leggings", "Boots", "Helmet", "Chestplate" }
and in my list view I want the end result to be like this.
Diamond leggings
Diamond boots
Diamond Helmet
Diamond Chestplate
Iron Leggings
...
...
Gold Leggings
...
...
...
What would I need to do to achieve that? I think it would be ineffecient if I did it like this
test3.add("Diamond Chestplate")
test3.add("Diamond boots")
etc..
..
...
and end up having big list instead where I can combine them.
Use 2 nested for loops to merge the arrays:
String test1[] = {"Diamond", "Iron", "Leather"};
String test2[] = {"Leggings", "Boots", "Helmet", "Chestplate"};
List<String> merged = new ArrayList<String>();
for (String str1 : test1) {
for (String str2 : test2)
merged.add(str1 + " " + str2);
}
System.out.println(merged);
If I understand your question, you could do with nested For-Each Loop(s) like
String test1[] = { "Diamond", "Iron", "Leather" };
String test2[] = { "Leggings", "Boots", "Helmet", "Chestplate" };
List<String> al = new ArrayList<>();
for (String i : test1) {
for (String j : test2) {
StringBuilder sb = new StringBuilder(i);
sb.append(' ').append(j);
al.add(sb.toString());
}
}
System.out.println(al);
I am curious to know that If, I can achieve it in a single loop.
How to do it, and finally I have done it.
private static String test1[] = {"Diamond", "Iron", "Leather"};
private static String test2[] = {"Leggings", "Boots", "Helmet", "Chestplate"};
public static void doInSingleLoop() {
int maxLength = test1.length * test2.length;
List<String> al = new ArrayList<String>();
for (int i = 0; i < maxLength; i++) {
String t1 = test1[i / test2.length];
String t2 = test2[i % test2.length];
StringBuilder sb = new StringBuilder(t1);
sb.append(' ').append(t2);
al.add(sb.toString());
}
System.out.println(al);
}
Check below example.
public static void main(String[] args) {
String firstNameArr[] = { "diamond", "Iron", "Leather" };
String lastNameArr[] = { "Leggings", "Boots", "Helmet"};
List<String> fullNameList = new ArrayList<String>();
for (String firstname : firstNameArr) {
for(String lastName : lastNameArr){
fullNameList.add((firstname+" "+lastName));
}
}
}
i am making a project about turing machine and i am having a problem about the how do i replace a character in an certain index of a string
Example: if i input in the initial tape:
stackoverflow
then code in the inputArea like
write 1
the output should be
1tackoverflow
but sadly the output of my code is
11111111111111
I'm trying to get rid of the loop because i know my loop is the problem but how should i do it ?
Here's my code
runButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ActE){
String[] iniTape = iTapeArea.getText().split("");
String[] input = inputArea.getText().split("\n");
for(int i=0;i<input.length;i++)
{
if(input[i].contains("write")==true){
sub = input[i].substring(6, input[i].length());
for(int j=0;j<iniTape.length;j++){
System.out.print(""+iniTape[j].replace(iniTape[j], sub));
}
}
}
}
});
No need to try this hard. You can use
String str = "stackoverflow";
System.out.println(str.replace("" + str.charAt(0), "1"));
Out put:
1tackoverflow
Use replaceAll() method of String class as below
yourString.replaceAll("" + yourString.charAt(index), "1")//index is your index at which you want to replace
""+ is equivalent of doing String.valueOf(yourString.charAt(index))
This might do the trick
String[] iniTape = iTapeArea.getText().split("");
String sub= null;
String temp = null;
String[] input = inputArea.getText().split("\n");
//"test 1\ntest 2\ntest 3".split("\n");
for(int i=0;i<input.length;i++)
{
if(input[i].contains("write")==true){
sub = input[i].substring(6, input[i].length());
iniTape[i+1] = sub;
}
}
StringBuffer buffer = new StringBuffer();
for(String str : iniTape) {
buffer.append(str);
}
System.out.println(buffer.toString());
replace the index value with the required character
I use the replaceFirst(String, String) function of the String class.
public static void main(String[] args) {
String s = "stackoverflow";
s = s.replaceFirst("" + s.charAt(0), "1");
System.out.println(s);
}
If you want to replace a given certain indexes of a string with that number you can do the following
static String str = "stackoverflow";
public static String replaceCharsAt(int ... indices) {
for (int index : indicies) {
str = str.replace(str.charAt(i), i+1);
}
return str;
}
I have struct Array or List String like:
{ "A.B", "B.A", "A.C", "C.A" }
and I want delete reverse string from list that end of only:
{ "A.B", "A.C" }
how type String use and how delete reverse String?
To reverse a string I recommend using a StringBuffer.
String sample = "ABC";
String reversed_sample = new StringBuffer(sample).reverse().toString();
To delete object form you ArrayList use the remove method.
String sample = "ABC";String to_remove = "ADS";
ArrayList<String> list = new ArrayList<Sample>();
list.add(to_remove);list.add(sample );
list.remove(to_remove);
You can get use of a HashMap to determine whether a string is a reversed version of the other strings in the list. And you will also need a utility function for reversing a given string. Take a look at this snippets:
String[] input = { "A.B", "B.A", "A.C", "C.A" };
HashMap<String, String> map = new HashMap<String, String>();
String[] output = new String[input.length];
int index = 0;
for (int i = 0; i < input.length; i++) {
if (!map.containsKey(input[i])) {
map.put(reverse(input[i]), "default");
output[index++] = input[i];
}
}
A sample String-reversing method could be like this:
public static String reverse(String str) {
String output = "";
int size = str.length();
for (int i = size - 1; i >= 0; i--)
output += str.charAt(i) + "";
return output;
}
Output:
The output array will contain these elements => [A.B, A.C, null, null]
A code is worth thousand words.....
public class Tes {
public static void main(String[] args) {
ArrayList<String> arr = new ArrayList<String>();
arr.add("A.B");
arr.add("B.A");
arr.add("A.C");
arr.add("C.A");
System.out.println(arr);
for (int i = 0; i < arr.size(); i++) {
StringBuilder str = new StringBuilder(arr.get(i));
String revStr = str.reverse().toString();
if (arr.contains(revStr)) {
arr.remove(i);
}
}
System.out.println(arr);
}
}
You can do this very simply in O(n^2) time. Psuedocode:
For every element1 in the list:
For every element2 in the list after element1:
if reverse(element2).equals(element1)
list.remove(element2)
In order to make your life easier and prevent ConcurrentModificationException use Iterator. I won't give you the code because it's a good example to learn how to properly use iterators in Java.
Reverse method:
public String reverse(String toReverse) {
return new StringBuilder(toReverse).reverse().toString();
}
Edit: another reverse method:
public String reverse(String toReverse) {
if (toReverse != null && !toReverse.isEmpty) {
String[] elems = toReverse.split(".");
}
StringBuilder reversedString = new StringBuilder("");
for (int i = elems.length - 1; i >= 0; i++) {
reversedString.append(elems[i]);
reversedString.append(".");
}
return reversedString.toString();
}
Check this
public static void main(String arg[]){
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
List<String> strList = new ArrayList<String>();
strList.add("A.B");
strList.add("B.A");
strList.add("A.C");
strList.add("C.A");
Iterator<String> itr = strList.iterator();
while(itr.hasNext()){
String [] split = itr.next().toUpperCase().split("\\.");
if(str.indexOf(split[0])>str.indexOf(split[1])){
itr.remove();
}
}
System.out.println(strList);
}
output is
[A.B, A.C]
You can iterate the list while maintaining a Set<String> of elements in it.
While you do it - create a new list (which will be the output) and:
if (!set.contains(current.reverse())) {
outputList.append(current)
set.add(current)
}
This solution is O(n*|S|) on average, where n is the number of elements and |S| is the average string length.
Java Code:
private static String reverse(String s) {
StringBuilder sb = new StringBuilder();
for (int i = s.length()-1 ; i >=0 ; i--) {
sb.append(s.charAt(i));
}
return sb.toString();
}
private static List<String> removeReverses(List<String> arr) {
Set<String> set = new HashSet<String>();
List<String> res = new ArrayList<String>();
for (String s : arr) {
if (!set.contains(reverse(s))) {
res.add(s);
set.add(s);
}
}
return res;
}
public static void main(String[]args){
String[] arr = { "a.c" , "b.c", "c.a", "c.b" };
System.out.println(removeReverses(arr));
}
will yield:
[a.c, b.c]