Converting arraylist int to string - java

I am trying to convert an arraylist of integers to an string in reverse.
eg (1,2,3,4) converts to "4321".
However I am unable to get my code to work mainly due to the primitive data type error (basically why you give my an arraylist to do an array thing). My code is currently
public String toString() {
int n = arrList.size();
if (n == 0)
return "0";
for (int i = arrList.size(); i > 0; i--);
int nums= arrList[i];
char myChar = (char) (nums+ (int) '0');
String result = myChar.toString(arrList);
return result;
}

Your loop had the wrong range and it didn't do anything, since you terminated it with ;.
In addition, arrList[i] is the way to access an element of an array. To access an element of an ArrayList you use arrList.get(i).
Finally, you should accumulate the characters / digits somewhere before converting them to a String. I suggest a StringBuilder.
StringBuilder sb = new StringBuilder();
for (int i = arrList.size() - 1; i >= 0; i--) {
int num = arrList.get(i);
sb.append(num);
}
String result = sb.toString();

You have many problems. First, you should remove ; after the for loop.
Second, you are not concatenating the result, just saving the last value.
Third, you should loop from the last index, which is arrList.size() - 1.
Fourth, note that the element at place 0 should be counted as well, so you should change your condition to i >= 0. Finally, accessing arraylist's elements should be done using the method get: arrList.get(i).
Now after you understood what your problems are, I would like to suggest a better solution using Java 8:
Collections.reverse(arrList);
String listString = arrList.stream().map(Object::toString)
.collect(Collectors.joining(""));

public String toString() {
int n = arrList.size();
if (n == 0)
return "0";
String str = "" ;
for (int i = arrList.size()-1; i > 0; i--){
int nums= arrList.get(i);
str+= nums ;
}
return str;
}

A ListIterator works too - if you dont want indexing.
ArrayList<Integer> integerList = new ArrayList<Integer>();
StringBuilder sb = new StringBuilder();
ListIterator<Integer> it = integerList.listIterator(integerList.size());
while(it.hasPrevious())
{
sb.append(Integer.toString(it.previous()));
}
String answer = sb.toString();

Related

String Array to String without last index value

I am working with String and String[] in java.
I have one String[] and wanted to convert into String but don't want last index value in it.
String[] arr = new String[]{"1","2","3","4"};
I want new string as 123 only.
Yes, I can iterate arr up to second last index maintain assign the value in the new string. But is there any other way to this thing in the smarter way?
I think about three ways.
First one is using StringBuilder. This takes you full control with minimum garbage. (I would prefer this one)
public static String convert(String... arr) {
// in case of arr is really big, then it's better to first
// calculate required internal buffer size, to exclude array copy
StringBuilder buf = new StringBuilder();
for(int i = 0; i < arr.length - 1; i++)
buf.append(arr[i]);
return buf.toString();
}
Another way is to use Java8 feature String.join():
public static String convert(String... arr) {
return String.join("", arr).substring(0, arr.length - 1);
}
And finally using Stream:
public static String convert(String... arr) {
return Arrays.stream(arr, 0, arr.length - 1).collect(Collectors.joining(""));
}
try this
String[] arr = new String[]{"1","2","3","4"};
String newString = "";
for (int i = 0; i < arr.length -1 ; i++) {
newString += arr[i];
}
System.out.print(newString);
Output
123

Efficient searching according to "starts with"

I facing some issue with write logic for below problem.
I have two ArrayLists of strings:
List1: contains 5 million strings
List2: will create on users input and contains some strings/characters(Ex. a,b,c,g,l,pd,sp,mta)
Now I have to split list1 into multiple Lists according to startsWith strings in list2 like in above case. I need to create 8 lists as starts with 'a', 'b','c', 'g', 'l','pd', 'sp' and 'mta'
But the condition for above is I have to iterate List1 or List2 only once. i.e. worst complexity for algorithm should be size of List1 (5 million).
It is allowed to use collections.sort() method
Code I have tried
// Create List for search strings.
List<String> CharList = new ArrayList<String>();
CharList.add("a");
CharList.add("b");
CharList.add("e");
CharList.add("z");
CharList.add("4");
CharList.add("1");
CharList.add("zi");
List<String> recordList = new ArrayList<String>();
// Creating dummy data with 100 character in live environment it can be
// around 50 lakhs strings
for (int i = 0; i < 100; i++) {
char[] chars = "abcdefghijklmnopqrstuvwxyzABCGDKL0123456789".toCharArray();
StringBuilder sb = new StringBuilder();
Random random = new Random();
for (int i1 = 0; i1 < 6; i1++) {
char c = chars[random.nextInt(chars.length)];
sb.append(c);
}
String output = sb.toString();
recordList.add(output);
}
// Adding some data mannually
recordList.add("zink");
recordList.add("zebra");
recordList.add("zzzzzz");
Collections.sort(CharList, String.CASE_INSENSITIVE_ORDER);
Collections.sort(recordList, String.CASE_INSENSITIVE_ORDER);
System.out.println("RECORDLIST ===>" + recordList);
System.out.println("***************************************************");
System.out.println("Charlist ===>" + CharList);
System.out.println("***************************************************");
List<List> lists = new ArrayList<List>();
int startIndex = 0, charPointer = 0;
while (startIndex < recordList.size() && charPointer < CharList.size()) {
List<String> temp = new ArrayList<String>();
boolean isHit = false;
String currentRecord = recordList.get(startIndex);
String partitionSattement = CharList.get(charPointer);
while (currentRecord.startsWith(partitionSattement.toUpperCase())
|| currentRecord.startsWith(partitionSattement.toLowerCase())) {
temp.add(recordList.get(startIndex));
isHit = true;
startIndex++;
}
if (!isHit) {
startIndex++;
}
if (!temp.isEmpty()) {
lists.add(temp);
System.out.println(CharList.get(charPointer) + "====>" + temp);
}
charPointer++;
}
Just using the String startsWith method won't work in this case. Consider what happens if the first pattern does not match any input - you'll loop through all strings in the input list without finding a match, even though subsequent pattern matches do exist.
What we need to do instead is compare each pattern against the initial characters of each input string and process accordingly. Let's say we have an input string str and a pattern pat. Let subStr be the first pat.length() characters of str. Now we can compare subStr and pat using the String compareToIgnoreCase method. There are three cases to consider:
subStr < pat Move to the next input string.
subStr == pat Add str to output for pat and move to the next input string.
subStr > pat Move to the next pattern.
Here's some code to illustrate (I've kept your variable names where possible).
List<List<String>> output = new ArrayList<>();
for(int i=0; i<CharList.size(); i++) output.add(new ArrayList<String>());
int startIndex=0;
int charPointer=0;
while(startIndex < recordList.size() && charPointer < CharList.size())
{
String charStr = CharList.get(charPointer);
String recStr = recordList.get(startIndex);
int cmp;
if(recStr.length() < charStr.length())
{
cmp = -1;
}
else
{
String recSubStr = recStr.substring(0, charStr.length());
cmp = recSubStr.compareToIgnoreCase(charStr);
}
if(cmp <= 0)
{
if(cmp == 0) output.get(charPointer).add(recStr);
startIndex++;
}
else
{
charPointer++;
}
}
for(int i=0; i<CharList.size(); i++)
{
System.out.println(CharList.get(i) + " : " + output.get(i));
}
Also, you should note that when you include a pattern that itself starts with another pattern (e.g. "zi" and "z") the longer pattern will never be matched, since the shorter one will capture all inputs.
I can see two problems in your code:
You should remove the following segment:
if (!isHit) {
startIndex++;
}
Actually you don't need that isHit variable at all. If a string doesn't match with a pattern then you still have to compare it with the next pattern.
You should sort the arrays in descending order. As SirRaffleBuffle noted in the other answer you should compare the strings with the longer pattern first. Sorting the strings and patterns in descending order will automatically solve this problem.

Best way to concatenate Strings in java(Time efficiency)

I checked many discutions about the best way to concatenate many string In Java.
As i understood Stringbuilder is more efficient than the + operator.
Unfortunantly My question is a litlle bit different.
Given the string :"AAAAA", how can we concatenate it with n times the char '_',knowing that the '_' has to come before the String "AAAAA"
if n is equal to 3 and str="AAAAA", the result has to be the String "___AAAAA"
String str = "AAAAA";
for (int i=0;i<100;i++){
str="_"+str;
}
In my program i have a Longs String , so i have to use the efficient way.
Thank you
EDIT1:
As I have read some Solutions I discovered that I asked for Only One Case , SO I arrived to this Solution that i think is good:
public class Concatenation {
public static void main(String[] args) {
//so str is the String that i want to modify
StringBuilder str = new StringBuilder("AAAAA");
//As suggested
StringBuilder space = new StringBuilder();
for (int i = 0; i < 3; i++) {
space.append("_");
}
//another for loop to concatenate different char and not only the '_'
for (int i = 0; i < 3; i++) {
char next = getTheNewchar();
space.append(next);
}
space.append(str);
str = space;
System.out.println(str);
}
public static char getTheNewchar(){
//normally i return a rondom char, but for the case of simplicity i return the same char
return 'A';
}
}
Best way to concatenate Strings in Java: You don't.... Strings are immutable in Java. Each time you concatenate, you generate a new Object. Use StringBuilder instead.
StringBuilder sb = new StringBuilder();
for (int i=0;i<100;i++){
sb.append("_");
}
sb.append("AAAAA");
String str = sb.toString();
Go to char array, alloting the right size, fill the array, and sum it up back into a string.
Can’t beat that.
public String concat(char c, int l, String string) {
int sl = string.length();
char[] buf = new char[sl + l];
int pos = 0;
for (int i = 0; i < l; i++) {
buf[pos++] = c;
}
for (int i = 0; i < sl; i++) {
buf[pos++] = string.charAt(i);
}
return String.valueOf(buf);
}
I'd do something like:
import java.util.Arrays;
...
int numUnderbars = 3;
char[] underbarArray = new char[numUnderbars];
Arrays.fill(underbarArray, '_');
String output = String.valueOf(underbarArray) + "AAAA";
but the reality is that any of the solutions presented would likely be trivially different in run time.
If you do not like to write for loop use
org.apache.commons.lang.StringUtils class repeat(str,n) method.
Your code will be shorter:
String str=new StringBuilder(StringUtils.repeat("_",n)).append("AAAAA").toString();
BTW:
Actual answer to the question is in the code of that repeat method.
when 1 or 2 characters need to be repeated it uses char array in the loop, otherwise it uses StringBuilder append solution.

How to return a string without the first character using an array

How do I return a string e.g. H4321 but return the numbers only, not the H. I need to use an array. So far I have:
char [] numbers = new char[5];
return numbers;
Assuming I need a line between those two. String is called value
You can use substring method on String object.
Like this:
String newValue = value.substring(1);
and then call: char[] charArray = newValue.toCharArray();
Another solution - it copies old array without first element. :
char[] newNumbers = Arrays.copyOfRange(numbers, 1, numbers.length);
Use the code bellow:
public String getNumber(){
char [] numbers = new char[5];
numbers = new String("H4321").toCharArray();
String result = "";
for(int i = 0; i < numbers.length ; i++){
if(Character.isDigit(numbers[i])){
result += numbers[i];
}
}
return result;
}

Java find difference between characters in StringBuffer

I'm working on an Anagram program and I'm currently working on a method called diff which should return a StringBuffer containing the chars that are in the first StringBuffer but not in the second one. So for example if the StringBuffers are abba and acca, then my diff method should return bb. So far I currently have loop with an if statement but it's not working. Any help would be appreciated. Thanks
public StringBuffer diff(){
StringBuffer diffVal = null;
for (int i =0; i < sBuffer1.length(); i++){
String let1 = String.valueOf(sBuffer1);
if (sBuffer2.indexOf(let1) == -1 ){
}
}
return diffVal;
I think you are trying to use a loop to examine one character by one character in sBuffer1. But String let1 = String.valueOf(sBuffer1); gives you the entire string of sBuffer1.
What you need is String let1 = sBuffer1.substring(i, i + 1) to take a single character from sBuffer1 to check if it exists in sBuffer2.
For example:
public static StringBuffer diff(StringBuffer sBuffer1, StringBuffer sBuffer2) {
StringBuffer diffVal = new StringBuffer();
for (int i = 0; i < sBuffer1.length(); i++) {
String let1 = sBuffer1.substring(i, i + 1); // get the character from sBuffer1
if (sBuffer2.indexOf(let1) == -1) {
diffVal.append(let1); // append the character to the diff
}
}
return diffVal;
}
ok this might work, your logic was a little bit wrong, this code is straight forward. search for the character if it doesn't exist in the second string buffer add it to the result SF.
public StringBuffer diff(){
StringBuffer diffVal = new StringBuffer();//initialize before you use it.
for (int i =0; i < sBuffer1.length(); i++){
String let1 = String.valueOf(sBuffer1.charAt(i))//get the character at the ith position.
if (sBuffer2.indexOf(let1) == -1 ){
diffVal.append(let1);
}
}
return diffVal;
}
Try this.
StringBuilder diffVal= new StringBuilder();
StringBuffer sBuffer1 = new StringBuffer("abbad");//input 1
StringBuffer sBuffer2 = new StringBuffer("acca");//input 2, you can ignore if you have already passed/defined these
for (int i =0; i < sBuffer1.length(); i++){
if(i >= sBuffer2.length()){//handles difference in input string length
diffVal.append(sBuffer1.substring(i, sBuffer1.length()));
break;
}
if (sBuffer1.charAt(i) != sBuffer2.charAt(i)) {
diffVal.append(sBuffer1.charAt(i));
}
}
System.out.println(diffVal);// I am printing it here
the out put is : bbd
One recommendation here is use StringBuilder if you the strings you are using here are not required to be synchronized

Categories