I have a stream of strings from a csv file. These strings are converted to arrays and must be put in an Object's setter and the Object in a hashMap as a value. How do i concatenate all comming Arrays into one and only then use the Set method? Is there any better solution than concatenating the arrays before the set method?
Here is my code:
HashMap<Integer, Publication> innerMap = new HashMap<>();
try {
CsvReader csv = new CsvReader(filename);
csv.readHeaders();
while (csv.readRecord()) {
int id = Integer.parseInt(csv.get("ID"));
Publication pub = new Publication();
String names = csv.get("Names");
String[] namesArr = names.split(",");
if (!innerMap.containsKey(id)) {
innerMap.put(id, new Publication());
}
String[] merged = ????
pub.setNames(merged);
innerMap.put(au.getIdx(), pub);
}
csv.close();
} catch (IOException e) {
System.out.println("Exception : " + e);
}
Store them in a List first:
List<String[]> list = new ArrayList<>;
...
list.add(namesArr);
Then, once you've finished reading:
int size = 0;
for (String[] arr : list) {
size += arr.length;
}
List<String> all = new ArrayList<>(size);
for (String[] arr : list) {
all.addAll(Arrays.asList(arr));
}
The first loop helps to allocate the necessary memory to hold all of the data (otherwise there may be lots of reallocations and array copying in the ArrayList internally while you are adding elements to it in the second loop).
this has already been answered using Apache commons - How can I concatenate two arrays in Java?
Here's a pure java 8 way
String[] arr1 = { "a", "b", "c", "d" };
String[] arr2 = { "e", "f", "g" };
Stream<String> stream1 = Stream.of(arr1);
Stream<String> stream2 = Stream.of(arr2);
String[] arr = Stream.concat(stream1, stream2).toArray(String[]::new);
It looks like that if the map key exists, you want to extract the values, append additional values and then put it back in.
I would use a getter, then run this concat function which returns a new array. Since an Array is capped by its size, you cant grow it unless you make a new array and copy everything over.
to concat 2 string arrays where A comes first:
String[] concat( String[] a, String[] b){
String[] out = new String[a.length + b.length]();
int i = 0;
for (int j = 0; j < a.length; j++){
out[i] = a[j]
i++;
}
for (int j = 0; j < b.length; j++){
out[i] = b[j];
i++;
}
return out;
}
Related
For eg.,
the input array is :
String array = {"0","0","0","K","K","B","P","P","P","Z",
"Z","D","D","E","E","F","N","O","O}
Output:
first sub-array = {"O,O,O"}
second sub-array = {"K","K"}
third sub-array = {"O","O"}
You can do this using stack for that checkout below code for that.
String data[] = { "0", "0", "0", "K", "K", "B", "P", "P", "P", "Z", "Z", "D", "D", "E", "E", "F", "N" };
// a = ['0','0','0','K','K','P','P','P','Z']
Stack<String> stack = new Stack<String>();
String prevValue = data[0];
for (int i = 1; i < data.length; i++) {
if (data[i].equals(data[i - 1])) {
prevValue = prevValue + data[i];
} else {
stack.push(prevValue);
prevValue = data[i];
}
}
stack.push(prevValue);
System.out.println(stack);
Assuming you don't know how many different characters you're looking for one possible solution would be using a Map:
Map<String,List<String>> map = new HashMap<>();
for(int i = 0; i < array.length; i++){
if(map.containsKey(array[i])
map.get(array[i]).add(array[i]);
else
map.put(array[i],array[i]);
}
However, personally I think what you're asking can be simplified with a Parameter style approach. This is, instead of storing each ocurrence of each string pattern you're looking for, you simply store a counter. So, and still assuming that you don't know how many distinct patterns you're looking for,you could do this:
Map<String,Integer> map = new HashMap<>();
for(int i = 0; i < array.length; i++){
map.put(array[i], new Integer(map.get(array[i]).intValue() + 1);
}
You can create a map with string as index and integer as value.
Then you can loop this array and assign the values of array as index of the map and keep increasing the integer value.
For example, you can add these lines inside the loop, and you will have a map:
Map<String, Integer> myCharMap = new HashMap<String, Integer>();
myCharMap.put(array[index], new Integer(myCharMap.get(array[index]).intValue()+1));
If you're looking for continuous regions, you can use looping since the order matters.
List<List<String>> continuous = new ArrayList<>();
List<String> current;
String last = null;
for(String s: array){
if(!s.equals(last)){
current = new ArrayList<>();
continuous.add(current);
}
current.add(s);
last=s;
}
In your example, you could use a stream and the grouping by collector since the regions are also unique characters.
Map<String, List<String>> grouped = Arrays.stream(array).collect(
Collectors.groupingBy(String::toString)
);
If you really need the String[] instead of List, you can use List.toArray.
String[] arr_version = grouped.get("0").toArray(new String[0]);
This question already has answers here:
Create ArrayList from array
(42 answers)
Closed 6 years ago.
I would like to convert an Array of Strings into an ArrayList of ArrayList, where the inner ArrayList has a dynamic number of elements. Who can help ? Thanks in advance
String[] sentences = {"hello","how are you","i am fine","and you ?","thank you"}
//Output with number of elements = 2
["hello","how are you"]
["i am fine","and you ?"]
["thank you"]
//Output with number of elements = 3
["hello","how are you","i am fine"]
["and you ?","thank you"]
public static void main(String[] args) {
String[] sentences = {"hello", "how are you", "i am fine", "and you ?", "thank you"};
System.out.println(split(2,sentences));
System.out.println(split(3,sentences));
}
public static List<List<String>> split(int numberOfElements, String[] sentences) {
List<List<String>> lists = new ArrayList<List<String>>();
int index = 0;
for (String sentence : sentences) {
if (index % numberOfElements == 0) {
lists.add(new ArrayList<String>());
}
lists.get(index / numberOfElements).add(sentences[index]);
index++;
}
return lists;
}
Output:
[[hello, how are you], [i am fine, and you ?], [thank you]]
[[hello, how are you, i am fine], [and you ?, thank you]]
public static void main(String[] args) {
String[] sentences = { "hello", "how are you", "i am fine", "and you ?", "thank you" };
List<List<String>> convertIntoList = convertIntoList(sentences, 2);
System.out.println(convertIntoList);
convertIntoList = convertIntoList(sentences, 3);
System.out.println(convertIntoList);
}
private static List<List<String>> convertIntoList(String[] sentences, int nbElement) {
List<List<String>> listOfListTarget = new ArrayList<List<String>>();
int currentIndex = 0;
while (currentIndex < sentences.length) {
int nextIndex = currentIndex + nbElement;
if (nextIndex > sentences.length) {
nextIndex = sentences.length;
}
final String[] copyOfRange = Arrays.copyOfRange(sentences, currentIndex, nextIndex);
List<String> subList = new ArrayList<String>();
subList.addAll(Arrays.asList(copyOfRange));
listOfListTarget.add(subList);
currentIndex+=nbElement;
}
return listOfListTarget;
}
Is this is a homework?
So you have an array of strings, and you want to create a List> with that, with each inner List containing at most x number of elements.
To get x number of elements and put them in a List, you can do a simple for loop.
String[] myStringArray = { ... };
List<String> myListOfString = new ArrayList<>();
for(int i=0; i<x; i++) {
myListOfString.add(myStringArray[i]);
}
So for example if you have these values
String[] myStringArray = {"a", "b", "c", "d", "e"};
x = 2;
You'll get the following list using the above loop:
["a", "b"]
Great! But we need to get all the contents of the myStringArray! How do we do that? Then let's do the first step, we iterate through all the contents of the array. We can do that like this.
int i=0;
while(i < myStringArray.length) {
System.out.println(myStringArray[i]);
i++;
}
Which will output:
a
b
c
d
e
This doesn't solve the problem... but at least we know how to iterate the whole thing. The next step is to get x of them. Sounds simple right? So basically we need to create a list of x from the contents. Maybe we can use the logic we created a few examples back to solve the problem.
// Create list of list of string here
int i = 0;
while(i < myStringArray.length) {
// Create list of string here
for(int j=0; j<x; j++) {
// Add myStringArray[j] to list of string here
}
// Add the list of string to the list of list of string here
i++;
}
Easy right? No. This gives the following lists:
["a", "b"]
["a", "b"]
["a", "b"]
["a", "b"]
["a", "b"]
Why? In the first loop, we are iterating up to how many is in the array. In the second loop, we are adding element 0 and 1 to a list. Obviously it wouldn't work. The second loop needs to be aware that it should not add previously added elements, and at the same time the first loop needs to be aware of what the second loop is doing. So you might think, maybe we can use the int i to indicate where the second loop should start?
int i = 0;
while(i<myStringArray.length) {
while(i<x) {
// add myStringArray[i];
i++;
}
i++;
}
Unfortunately, using the same values as previous, this will only give the following list
["a", "b"]
Because i is iterating through the whole array. So when it goes from 0 to length, whatever the value of i is used on the second array. When it loops again, i becomes 1, so the start of the second loop is at 1.
We need a separate variable to do the counting, while still keeping in mind where we currently are in the second loop.
int i = 0;
while(i<myStringArray.length) {
int count = 0;
while(count < x) {
// Add myStringArray[count+i] to list of string
count++;
}
// Add to list of list of string
i += count + 1; // Need to be aware of how much we have processed
}
This will do what we want, but unfortunately we can get in trouble at certain values. Say x is 10 and myStringArray is only of length 2. This will throw an exception because when it reaches the point of count+i = 3, that index doesn't exist anymore. The second loop also needs to be aware of how much is still remaining.
Finally we'll have the following code
int i = 0;
while(i<myStringArray.length) {
int count = 0;
while(count < x && count+i < myStringArray.length) {
// Add myStringArray[count+i] to list of string
}
// Add to list of list of string
i += count; // Need to be aware of how much we have processed
}
Which will give
["a", "b"]
["c", "d"]
["e"]
Edit: Next time try to put some code that you tried something.
I want to make a for-loop to add a letter to each string object in my list. I'm just not sure how to edit the objects in the list and not the actual list.
for instance, if I wanted to add "ing" to the end of each object in my list..
I feel like it's something simple, but I've been looking through oracle forever and haven't been able to figure it out if anyone can point me in the right direction?
I could use any kind of list really.. just anything that works.
I was thinking something like,
String[] stringArray = tools.toArray(new String[0]);
for (int i = 0; i < stringArray.length; i++)
{
stringArray[i] = stringArray[i].*part that would modify would go here*
}
You cannot edit a String. They are immutable. However, you can replace the entry in the list.
ArrayList<String> list = new ArrayList<>();
list.add("load");
list.add("pull");
for (int i = 0; i < list.size(); ++i) {
list.set(i, list.get(i) + "ing");
You updated your question to specify a static array:
stringArray[i] = stringArray[i] + "ing";
The right side of the assignment is performing a String concatenation which can be done with the + operator in Java.
You can use StringBuilder for this purpose.
public static void addIng(String[] arr) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
sb.setLength(0);
sb.append(arr[i] + "ing");
arr[i] = sb.toString();
}
}
Strings are immutable in java; they can't be modified once created.
Here it seems you have a few options; you can create a method that takes your list and returns a new list, by appending 'ing' to the end of each string in the list.
Alternatively, if you need to keep a reference to the original list, you can loop over the contents of the list (ArrayList?) and pop each string out, create a new string with the appended 'ing', and replace in the list.
Something like
List<String> list = new ArrayList<>();
list.add("testing");
for(String s:list){
s=s+"ing";
}
Please take a look below samples.
//Java 8 code.
List<String> oldList = Arrays.asList("a", "b");
List<String> newList = oldList.stream().map(str -> new StringBuilder(str).append("ing").toString()).collect(Collectors.toList());
System.out.println(oldList); // [a, b]
System.out.println(newList); // [aing, bing]
// Java 7 or below.
List<String> oldList = Arrays.asList("a", "b");
List<String> newList = new LinkedList<String>();
for (String str : oldList) {
newList.add(new StringBuilder(str).append("ing").toString());
}
System.out.println(oldList); // [a, b]
System.out.println(newList); // [aing, bing]
I am trying to remove duplicated words from an array, and I keep getting null values. I'm not allowed to use java sorting methods so I have to develop my own. Here's my code:
public class Duplicate{
public static void main(String[] args){
String[] test = {"a", "b", "abvc", "abccc", "a", "bbc", "ccc", "abc", "bbc"};
removeDuplicate(test);
}
public static String[] removeDuplicate(String[] words){
boolean [] isDuplicate = new boolean[words.length];
int i,j;
String[] tmp = new String[words.length];
for (i = 0; i < words.length ; i++){
if (isDuplicate[i])
continue;
for(j = 0; j < words.length ; j++){
if (words[i].equals(words[j])) {
isDuplicate[j] = true;
tmp[i] = words[i];
}
}
}
for(i=0;i<words.length;i++)
System.out.println(tmp[i]);
return tmp;
}
}
I tried doing
if(words == null)
words == "";
But it doesn't work. I also want to return the tmp array with a new size.
For example, test array length = 9, after removing the duplicates,I should get a new array with a length of 7.Thank you for your help.
EDIT:
result i get:
a
b
abvc
abccc
null
bbc
ccc
abc
null
You're getting nulls because the result array contains fewer words than the input array. However, you're constructing the arrays of the same length.
You don't have to sort to solve this problem. However, if you're not allowed to use the tools provided by java.utils, then this is either a poorly contrived test question or whomever told you not to use the Java utility classes is poorly informed.
You can solve without sorting by doing (assuming Java 1.5+):
public class Duplicate {
public static void main(String[] args) {
String[] test = {"a", "b", "abvc", "abccc", "a", "bbc", "ccc", "abc", "bbc"};
String[] deduped = removeDuplicate(test);
print(deduped);
}
public static String[] removeDuplicate(String[] words) {
Set<String> wordSet = new LinkedHashSet<String>();
for (String word : words) {
wordSet.add(word);
}
return wordSet.toArray(new String[wordSet.size()]);
}
public static void print(String[] words) {
for (String word : words) {
System.out.println(word);
}
}
}
The output will be:
a
b
abvc
abccc
bbc
ccc
abc
I would go for hashset to remove duplicates, it will remove duplicates since hash function for the same string will give same value, and duplicates will be eliminated. Then you can convert it to a string.
I would recommend doing this with a different approach. If you can use an ArrayList, why not just create one of those, and add the non-duplicate values to it, like this:
ArrayList<String> uniqueArrayList = new ArrayList<String>();
for(int i = 0; i < words.length; i++){
if(!uniqueArrayList.contains(words[i])){ // If the value isn't in the list already
uniqueArrayList.add(words[i]);
}
}
Now, you have an array list of all of your values without the duplicates. If you need to, you can work on converting that back to a regular array.
EDIT
I really think you should use the above option if you can, as there is no clean or decently efficient way to do this only using arrays. However, if you must, you can do something like this:
You can use the code you have to mark values as null if they are duplicates, and also create a counter to see how many unique values you have, like this:
int uniqueCounter = 0;
for(int i = 0; i < isDuplicate.length; i++){
if(!isDuplicate[i]){
uniqueCounter++;
}
}
Then, you can create a new array of the size of unique items, and loop through the words and add non-duplicate values.
String[] uniqueArray = new String[uniqueCounter];
int uniqueIndex = 0;
int wordsIndex = 0;
while(index < uniqueArray.length){
// Check if words index is not a duplicate
if(!isDuplicate[wordsIndex]){
// Add to array
uniqueArray[uniqueIndex] = words[wordsIndex];
uniqueIndex++; // Need to move to next spot in unique.
}
// Need to move to next spot in words
wordsIndex++;
}
Again, I HIGHLY recommend against something like this. It is very poor, and pains me to write, but for the sake of example on how it could be done using an array, you can try it.
I don't have the time to write functioning code, but I would reccomend to first sort the array using Arrays.sort(stringArray) and then loop throug the array coparing one string to the previous. Strings that match the previous one are duplicates.
Note: This method is probably not the fastest one and though only should be used on small arrays or in tasks where performance does not matter.
What about this approach?
public static String[] removeDuplicate(String[] words){
// remember which word is a duplicate
boolean[] isDuplicate = new boolean[words.length];
// and count them
int countDuplicate = 0;
for (int i = 0; i < words.length ; i++){
// only check "forward" because "backwards checked" duplicates have been marked yet
for(int j = i + 1; j < words.length ; j++){
if (words[i].equals(words[j])) {
isDuplicate[j] = true;
countDuplicate++;
}
}
}
// collect non-duplicate strings
String[] tmp = new String[words.length - countDuplicate];
int j = 0;
for (int i = 0; i < isDuplicate.length; i++) {
if (isDuplicate[i] == false) {
tmp[j] = words[i];
j++;
}
}
// and return them
return tmp;
}
Is this correct method to sort ArrayList?
The problem is that the list is not sorted.
out = new StringTokenizer(input.toString());
n = (out.countTokens());
for (int i = 0; i < n; i++) {
String[] words = { out.nextToken().toString() };
final List<String> wordList = Arrays.asList(words);
Collections.sort(wordList);
System.out.println(wordList.toString());
}
Each of your words[] arrays is composed of a single string, obtained from the next token of your StringTokenizer. And you are iterating in exact order of the tokenization. So yes, your output will not be sorted. I presume you wanted to do something like this:
out = new StringTokenizer(input.toString());
int count = out.countTokens():
List<String> wordList = new ArrayList<String>(count);
for(int i = 0; i < count; i++) {
wordList.add(out.nextToken());
}
Collections.sort(wordList);
But, don't use the tokenizer class, its legacy. The following code will serve you better:
List<String> wordList = Arrays.asList(input.split("\\s"));
Collections.sort(wordList);
out.nextToken().toString() give you one string. Your array length should be 1, I presume.
Even if you put this into a loop, you sort at each loop, you have to sort outside the loop.
StringTokenizer out = new StringTokenizer( input.toString());
List<String> wordList = new ArrayList< String >();
while( out.hasMoreTokens()) {
wordList.add( out.nextToken());
}
Collections.sort( wordList );
System.out.println(wordList.toString());