Zipping a list of strings in java - java

What would be the easiest / quickest way to zip a list of strings which is similar to this:
john,barry,stewart,josh,30,45,23,56
I want the order to be
john,30,barry,45,stewart,23,josh,56
I know that sounds like homework but the actual list is used in some selenium code and stores urls and the option of a radio button on the page but I thought the above example is simpler to read.

I would do something similar to this:
String[] parts = input.split(",");
int halfLength = parts.length / 2;
for (int i = 0; i < halfLength; i++) {
String name = parts[i];
String age = parts[i + halfLength];
// Store them in whatever structure you want here
}

What you need here is a zip function like in functional languages.
Functional java may help you out.
Related: Is there an accepted Java equivalent to Python's zip()?

Your question sounds like you need code to fix a bad design. Therefore, I would go a step back and ask the question how the list
john,barry,stewart,josh,30,45,23,56
was created, when you obviously need:
(john, 30), (barry, 45), (stewart, 23), (josh, 56)
(Replace the (x,y) notation with you favorite tuple type.)

Here you need to do some manual code.
Firstly scatter all the string and integer separately and obtain two list.
then just iterate one list and add these two list in one final list like first string and
then integer.

Looks like two lists
First generate two lists and create a new result list
Pseudocode :
list = Arrays.AsList(string.split("\\s+"))
list1 = list.sublist(0, list.size() /2 );
list2 = list.sublist(list.size() /2 +1 , list.size());
for(int i = 0;i<list1.size() ; i++ ) {
resultlist.add(list1.get(i);
resultlist.add(list2.get(i);
}
return resultlist

Try this way :
1. First sort it - the numbers will cover half the list and names half the list.
2. Create two arrays half the length : sArr1 and sArr2. Store numbers in sArr1 and names in sArr2.
3. Merge them by putting alternatively the number and the name from the two arrays into original array.
import java.util.Arrays;
public class SortMix {
public static void main(String[] args) {
String sArr[] = {"john","barry","stewart","josh","30","45","23","56"};
Arrays.sort(sArr);
display(sArr);
String sArr1[] = new String[sArr.length/2];
for(int i=0;i<sArr.length/2;i++)
sArr1[i] = sArr[i];
display(sArr1);
String sArr2[] = new String[sArr.length/2];
for(int i=0;i<sArr.length/2;i++)
sArr2[i] = sArr[i+sArr.length/2];
display(sArr2);
int k=0;
int l=0;
for(int i=0;i<sArr.length;i++) {
if(i%2==0){
sArr[i]=sArr1[k];
k++;
} else {
sArr[i]=sArr2[l];
l++;
}
}
display(sArr);
}
public static void display(String[] sArr) {
for(int i=0;i<sArr.length;i++)
System.out.print(sArr[i] + " ");
System.out.println();
}
}
Output would be :
23 30 45 56 barry john josh stewart
23 30 45 56
barry john josh stewart
23 barry 30 john 45 josh 56 stewart

Generic version of zip:
#SafeVarargs
public static <T> ArrayList<T> zip(Iterable<T> ...iterables) {
ArrayList<Iterator<T>> is = new ArrayList<>(iterables.length);
for (int i=0; i<iterables.length; i++) {
is.add(iterables[i].iterator());
}
ArrayList<T> al = new ArrayList<>();
while (is.get(0).hasNext()) {
for (int i=0; i<is.size(); i++) {
// FIXME: could check for shorter-than-expected sublists here
al.add(is.get(i).next());
}
}
return al;
}
Can be tested / called as follows:
public static void main(String[] args) {
List<String> parts =
Arrays.asList("john,barry,stewart,josh,30,45,23,56".split(","));
List<String> names = parts.subList(0, parts.size()/2);
List<String> numbers = parts.subList(parts.size()/2, parts.size());
System.err.println(zip(names, numbers));
}

It seems as if you are just trying to interleave the numbers and the alphanumerics. I would just scan the list in order to find the index of the first number than create a new list and take the first alpha and the first number and add them to the new list, then the second alpha and second number. This is not sorting and so is O(n)

Related

Print all the substrings of a given string in order by size

This code I'm using is from this previously asked question.
This question has been asked and answered plenty of times but I'm specifically asking for the order to be listed by size from largest to smallest.
public static void main(String[] args)
{
String inputedWord = "ABIGWORD";
for (String str : breakStringIntoPieces(inputedWord, 2))
{
System.out.print("\n") + str;
}
}
//Pass in word and minimum
//substring length to print
public static List<String> breakStringIntoAllPossibleSubstrings(String str, int num)
{
List<String> listOfSubstrings = new ArrayList<>();
Boolean insideLoop = false;
for(int i=0; i<=str.length()-num; i++)
{
for(int j=str.length(); j>=i+num; j--)
{
//System.out.println(str.substring(i, j));
if (insideLoop) //This is simply to not add the complete string to the
{ //list. Only substrings
listOfSubstrings.add(str.substring(i, j));
}
insideLoop = true;
}
}
return listOfSubstrings;
}
OUTPUT:
ABIGWOR
ABIGWO
ABIGW
ABIG
ABI
AB
BIGWORD
BIGWOR
BIGWO
BIGW
BIG
BI
IGWORD
IGWOR
IGWO
IGW
IG
GWORD
GWOR
GWO
GW
WORD
WOR
WO
ORD
OR
RD
DESIRED OUTPUT: (In no special order other than size. This is just a typed example.
ABIGWOR
BIGWORD
ABIGWO
BIGWOR
IGWORD
GWORD
ABIGW
IGWOR
BIGWO
IGWO
ABIG
BIGW
WORD
GWOR
GWO
ORD
ABI
BIG
IGW
WOR
AB
BI
IG
GW
WO
OR
RD
I could technically just loop through the returned list and find all the biggest substrings but that would add too many steps. I'm wondering if there's away to do it within the given method. I think the process involves manipulated the i and j iterators after each loop?
One simple way to achieve this with minimal changes would be to sort the listOfSubstrings ArrayList by length and then return the result. This will just be a one line change using Collections.sort.
public static List<String> breakStringIntoAllPossibleSubstrings(String str, int num) {
List<String> listOfSubstrings = new ArrayList<>();
/* Your code added here... */
// This will sort in descending order of length
Collections.sort(listOfSubstrings, (item1, item2) -> item2.length() - item1.length());
return listOfSubstrings;
}
In terms of time complexity, for a String of size N, generating all substrings is of the order O(N^2).
An extra sorting operation will introduce O(N^2 x log(N^2)) = O(N^2 x log(N)).
Therefore, overall complexity will be O(N^2 x log(N))

listing arraylist items inside another arraylist?

I just used the
ArrayList <ArrayList<String>> list = new ArrayList<ArrayList<String>>();
method for the first time and the output wasn't exactly in the way I wanted it to be.
I'm trying to make lists of different students and sorting them by what grade they're in. But, I am also trying to have a list that displays all the students, regardless of their grade. So this is the code that I was using:
ArrayList <ArrayList<String>> allStudents = new ArrayList<ArrayList<String>>();
ArrayList <String> gradeNines = new ArrayList();
ArrayList <String> gradeTens = new ArrayList();
ArrayList <String> gradeElevens = new ArrayList();
ArrayList <String> gradeTwelves = new ArrayList();
boolean firstSelection = true;
public void grade(String a, String b, ArrayList c)
{
a = jComboBox1.getSelectedItem() + "";
if (a.equals(b))
{
studentOutput.setText("");
int x = 0;
for (int indexNum = 0; indexNum < c.size(); indexNum++)
{
x = indexNum + 1;
studentOutput.append(num + ". " + c.get(indexNum) + "\n");
}
}
}
private void jComboBox1ActionPerformed(java.awt.event.ActionEvent evt) {
String studentGrade = jComboBox1.getSelectedItem() + "";
String all = "All Grades";
String nine = "Grade Nine";
String ten = "Grade Ten";
String eleven = "Grade Eleven";
String twelve = "Grade Twelve";
if (firstSelection)
{
Collections.addAll(allStudents, gradeNines, gradeTens, gradeElevens, gradeTwelves);
Collections.addAll(gradeNines, "Oscar", "Justin",....);
Collections.addAll(gradeTens, "Austin", "Jacob", "Evie"....);
Collections.addAll(gradeElevens, "Olivia", "Elizabeth"...);
Collections.addAll(gradeTwelves, "Ryan", "Jade"...);
firstSelection = false;
}
grade(studentGrade, all, allStudents);
grade(studentGrade, nine, gradeNines);
grade(studentGrade, ten, gradeTens);
grade(studentGrade, eleven, gradeElevens);
grade(studentGrade, twelve, gradeTwelves);
But the way this outputted, it was like:
[Oscar, Justin] 2. [Austin, Jacob, Evie] 3. [Olivia, Elizabeth] 4. [Ryan, Jade]
Is there a way to make it so that it outputs so that it shows each name individually like:
Oscar 2. Justin 3. Austin 4. Jacob ...
Firstly, these type of "grouping" problems are better handled using a Map (HashMap or an ordered implementation).
You could have the grades as the key and the list of student names as the values. That would feel as a better and easier way to handle collection data than a nested ArrayList.
Regarding your question,
Is there a way to make it so that it outputs so that it shows each name individually
No. These are separate ArrayLists. You will need to add/display them together, explicitly.
Further, I suggest you use the groupingBy function of Streams in Java 8. That will fit your use case very well.
With Streams, you could choose to display all items together OR group them by grades and display based on the chosen crteria(grade).
See this SO answer: https://stackoverflow.com/a/30202075/599851

How to print all non null elements of an array using Array.toString()

So I need to print out an array of integers. The problem is that when user enters the numbers to be processed and sorted, I do not know how many numbers there will be entered by the user. The only rule to that is that user can enter only less than 10000 numbers.
So I made an array which can hold 10000 numbers but if user enters less than 10000 numbers into the array then Array.toString() function prints out everything, even the empty spaces.
Is there any way to bypass that or are there any other methods for outputting an array in one line that would format it the output to look like this: [1, 2, 3, 4, 5, 6]
Thanks a lot!
It would be much easier to store the user's input in an ArrayList, and then just print myArryList.toString().
An ArrayList<T> (optionally <T> for generics). Is an array that dynamically adds more memory if more input comes available. The amortized cost of adding an element to such list is O(1), but it offers a convenient way to process input.
To answer your question, as #Mureinik already answered you then can use ArrayList.toString() to convert the list to a textual representation.
To answer your real question, you can do the following:
public static<T> String toStringArrayNonNulls (T[] data) {
StringBuilder sb = new StringBuilder();
sb.append("[");
int n = data.length;
int i = 0;
for(; i < n; i++) {
if(data[i] != null) {
sb.append(data[i].toString());
break;
}
}
for(; i < n; i++) {
if(data[i] != null) {
sb.append(",");
sb.append(data[i].toString());
}
}
sb.append("]");
return sb.toString();
}
And call that method with any type of array you want.
Examples
String[] names = new String[] {"Alice",null,"Charly","David",null,null};
System.out.println(toStringArrayNonNulls(names));
Integer[] primes = new Integer[] {2,3,null,null,11};
System.out.println(toStringArrayNonNulls(primes));
Object[] namesAndPrimes = new Integer[] {"Alice",2,null,3,null,"Charly",null,11};
System.out.println(toStringArrayNonNulls(namesAndPrimes));
If you want a dynamic array in Java, the best way is to learn how to use lists :
List<Integer> integers = new ArrayList<Integer>();
It prints only as many numbers as you put into it.
If you dont want to rewrite your program, this is also solution :
Integer[]x = new Integer[50];
List<Integer> integers = new ArrayList<Integer>();
integers = new ArrayList<Integer>(Arrays.asList(x));

Storing objects in arraylist

I have a small issue when I run into while using arraylists in Java. Essentially I am hoping to store an array in an arraylist. I know that arraylists can hold objects, so it should be possible, but I am not sure how.
For the most part my arraylist (which is parsed from a file) is just holding one character as a string, but once in a while it has a series of characters, like this:
myarray
0 a
1 a
2 d
3 g
4 d
5 f,s,t
6 r
Most of the time the only character I would care about in the string residing at position 5 is the f but occasionally I may need to look at the s or the t as well. My solution to this is to make an array like this:
subarray
0 f
1 s
2 t
and store subarray in position 5 instead.
myarray
0 a
1 a
2 d
3 g
4 d
5 subarray[f,s,t]
6 r
I tried to do this with this code:
//for the length of the arraylist
for(int al = 0; al < myarray.size(); al++){
//check the size of the string
String value = myarray.get(al);
int strsz = value.length();
prse = value.split(dlmcma);
//if it is bigger than 1 then use a subarray
if(strsz > 1){
subarray[0] = prse[0];
subarray[1] = prse[1];
subarray[2] = prse[2];
}
//set subarray to the location of the string that was too long
//this is where it all goes horribly wrong
alt4.set(al, subarray[]);
}
This isn't working the way I would like though. It won't allow me to .set(int, array). It only allows .set(int, string). Does anyone have suggestions?
The easiest approach would be to have an ArrayList of ArrayList.
ArrayList<ArrayList<String>> alt4 = new ArrayList<ArrayList<String>>();
However, this probably isn't the best solution. You may want to rethink your data model and look for a better solution.
Just change alt4.set(al, subarray[]); to
alt4.add(subarray);
I assume alt4 is another defined ArrayList<String[]>. If not, define it as below:
List<String[]> alt4= new ArrayList<String[]>();
or
ArrayList<String[]> alt4= new ArrayList<String[]>();
My guess is that you are declaring alt4 as List<String> and that's why it is not letting you set an array of String as a list element. You should declare it as List<String[]> and is each element is only singular, simply set it as the 0th element of the String[] array before adding it to the list.
You could switch to:
List<List<Character>> alt4 = new ArrayList<List<Character>>();
May be this is what you want to get
public class Tester {
List<String> myArrays = Arrays.asList(new String[] { "a", "a", "d", "g", "d", "f,s,t", "r" });
ArrayList<ArrayList<String>> alt4 = new ArrayList<ArrayList<String>>();
private void manageArray() {
// for the length of the arraylist
ArrayList<String> subarray = new ArrayList<String>();
for(int al = 0; al < myArrays.size(); al++) {
// check the size of the string
String value = myArrays.get(al);
int strsz = value.length();
String prse[] = value.split(",");
// if it is bigger than 1 then use a subarray
if(strsz > 1) {
for(String string : prse) {
subarray.add(string);
}
}
// set subarray to the location of the string that was too long
// this is where it all goes horribly wrong
alt4.set(al, subarray);
}
}
}

when using a array of strings in java, convert it to lowercase

I got a one dimensional array of strings in java, in which i want to change all strings to lowercase, to afterwards compare it to the original array so i can have the program check whether there are no uppercase chars in my strings/array.
i've tried using x.toLowercase but that only works on single strings.
Is there a way for me to convert the whole string to lowercase?
Kind regards,
Brand
arraylist.stream().map(s -> s.toLowerCase()).collect(Collectors.toList())
may help you
If you want a short example, you could do the following
String[] array = ...
String asString = Arrays.toString(array);
if(asString.equals(asString.toLowerCase())
// no upper case characters.
String array[]= {"some values"};
String str= String.join(',',array);
String array_uppercase[]=str.toLowerCase().split(',');
Just two line
String[] array = {"One", "Two"};
for(int i=0;i<array.length;i++){
if(!array[i].equals(array[i].toLowerCase()))
System.out.println("It contains uppercase char");
array[i] = array[i].toLowerCase();
}
for(int i=0;i<array.length;i++)
System.out.println(array[i]);
OUTPUT:
It contains uppercase char
It contains uppercase char
one
two
There's no easy way to invoke a method on every element of a collection in Java; you'd need to manually create a new array of the correct size, walk through the elements in your original array and sequentially add their lowercased analogue to the new array.
However, given what you're specifically trying to do, you don't need to compare the whole array at once to do this, and incur the cost of copying everything. You can simply iterate through the array - if you find an element which is not equal to its lowercase version, you can return false. If you reach the end of the array without finding any such element, you can return true.
This would in fact be more efficient, since:
you get to short-circuit further evaluation if you find an element that does have uppercase characters. (Imagine the case where the first element of a million-string array has an uppercase; you've just saved on a million calls to lowercase()).
You don't have to allocate memory for the whole extra array that you won't be using beyond the comparison.
Even in the best case scenario, your proposed scenario would involve one iteration through the array to get the lowercase versions, then another iteration through the array to implement the equals. Doing both in a single iteration is likely to be more efficient even without the possibility of short-circuiting.
Previously we used (In Java < 8)
String[] x = {"APPLe", "BaLL", "CaT"};
for (int i = 0; i < x.length; i++) {
x[i] = x[i].toLowerCase();
}
Now in Java8 :
x= Arrays.asList(x).stream().map(String::toLowerCase).toArray(String[]::new);
Two steps are needed:
Iterate over the array of Strings
Convert each one to lower case.
you can convert the array of strings to single string and then convert it into lower case and please follow the sample code below
public class Test {
public static void main(String[] args) {
String s[]={"firsT ","seCond ","THird "};
String str = " ";
for (int i = 0; i < s.length; i++) {
str = str + s[i];
}
System.out.println(str.toLowerCase());
}
}
import java.util.*;
public class WhatEver {
public static void main(String[] args) {
List <String> list = new ArrayList();
String[] x = {"APPLe", "BaLL", "CaT"};
for (String a : x) {
list.add(a.toLowerCase);
}
x = list.toArray(new String[list.size()]);
}
}
The following code may help you
package stringtoupercasearray;
import java.util.Scanner;
/**
*
* #author ROBI
*/
public class StringToUperCaseArray {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
int size;
String result = null;
System.out.println("Please enter the size of the array: ");
Scanner r=new Scanner(System.in);
size=r.nextInt();
String[] s=new String[size];
System.out.println("Please enter the sritngs:");
for(int i=0;i<s.length;i++){
s[i]=r.next();
}
System.out.print("The given sritngs are:");
for (String item : s) {
//s[i]=r.nextLine();
System.out.print(item+"\n");
}
System.out.println("After converting to uppercase the string is:");
for (String item : s) {
result = item.toUpperCase();
System.out.println(result);
}
}
}
You can do it with a single line of code. Just copy and paste the following snippet, without any looping at all.
String[] strArray = {"item1 Iteme1.1", "item2", "item3", "item4", "etc"}//This line is not part of the single line (=D).
String strArrayLowerCase[] = Arrays.toString(strArray).substring(1)
.replace("]", "").toLowerCase().split(",");
Happy String Life. =D

Categories