Here is the code, that works:
public class WorkshopApplicationMyCollection {
static void listOfPeople(List<String> someList) {
for (int i = 0; i<someList.size(); i++){
if (i == someList.size()-1) {
System.out.print(someList.get(i) + ". \n");
} else {
System.out.print(someList.get(i) + ", ");
}
}
}
public static void main(String[] args) {
List<String> listOfPeople = new ArrayList<>();
listOfAuthorities.add("Musk");
listOfAuthorities.add("Davinchie");
listOfAuthorities.add("Gates");
System.out.print("Number of people " + listOfPeople.size() + ". Those people are ");
listOfPeople(listOfAuthorities);
}
}
What I'm trying to do is to make a result of a method listOfPeople() to be a string by itself so that I could put it into the sentence. when I'm doing like this:
System.out.print("Number of people " + listOfPeople.size() + ". Those people are " + listOfPeople(listOfAuthorities));
the IDE says that the method has to not be void. How to make the method return string on it's own?
If you want to use the method in System.out.println it should return String instead of void. Think of void as a procedure that doesn't return anything. You want a method that returns String which can be used as a subject of printing out to a console.
(I prefer String.join(CharSequence delimiter, Iterable elements) to chain String elements:
static String listOfPeople(List<String> someList) {
return String.join(", ", someList) + ". \n";
}
Then it shall be used as:
System.out.print("Number of people " + listOfPeople.size() + ". Those people are " + listOfPeople(listOfPeople));
Your method should return a String, not call System.out.println directly. A common way of doing this is streaming the list and then joining it:
static String listOfPeople(List<String> someList) {
return someList.stream().collect(Collectors.joining(", ", "", ". \n"));
}
Well, a void function obviously returns nothing.
Here is a simple generic approach without using a Stream:
public static String flattenList(List<?> list)
{
StringBuilder sb = new StringBuilder();
for(int i = 0; i<list.size(); i++)
{
sb.append(list.get(i));
if(i < list.size()-1) sb.append(",");
else sb.append("\n");
}
return sb.toString();
}
If you just want to output the individual values, you can use something like that:
people.stream().forEach(System.out::println);
Use String.join("delimiter", list).
You coded wrong some name of variables, so I've corrected to you. Summarizing:
import java.util.ArrayList;
import java.util.List;
public class WorkshopApplicationMyCollection {
public static void main(String[] args) {
List<String> listOfAuthorities = new ArrayList<>();
listOfAuthorities.add("Musk");
listOfAuthorities.add("Davinchie");
listOfAuthorities.add("Gates");
System.out.print("Number of people " + listOfAuthorities.size() + ". Those people are " + String.join(" and ", listOfAuthorities));
}
}
Related
I've got a very strange question. Say I am implementing an object that has a toString() method that returns a single string formatted in a square, as such:
010203
040506
070809
Now, clearly the entire string, when listed character-wise (and excluding the terminating \0), is as such:
010203\n040506\n070809\n
How would I go about concatenating entire square blocks like these? For instance, if I wanted to have:
010203 101112 010203101112
040506 + 131415 = 040506131415
070809 161718 070809161718
How could I do this? Note that I cannot import Java.util or any other classes.
Edit:
The example above was merely an example; ideally I'd like the solution to be extensible to an arbitrarily large number of 'square objects', where I could just call a hypothetical aSquareObject.squareConcat(otherSquareObject).squareConcat(anotherSquareObject).....squareConcat(finalSquareObject) method and it'd spit out two, three, five, fifteen squares side by side.
public class T27Concat {
public static void main(String[] args) {
String s1 = "010203\n040506\n070809";
String s2 = "101112\n131415\n161718";
String plus = " \n + \n ";
String equals = " \n = \n ";
System.out.println(concat(concat(concat(concat(s1, plus), s2), equals), concat(s1, s2)));
}
public static String concat(String s, String t) {
String[] ss = s.split("\n");
String[] tt = t.split("\n");
String result = "";
for (int i = 0; i < ss.length; i++) {
result += ss[i] + tt[i] + "\n";
}
return result.substring(0, result.length() - 1);
}
}
public class multiDarr {
public static void main(String[] args) {
String str1 = "010203\n040506\n070809\n";
String str2 = "010203\n040506\n070809\n";
String ttl = "";
for(int i = 0;i<str1.length();i= i+7){
ttl = ttl + str1.substring(i,i+6);
ttl = ttl +str2.substring(i,i+6);
ttl = ttl+'\n';
}
System.out.println(ttl);
//System.out.println(ttl);
}
}
you have to tune i = i+ n for your need , i put 7 because your original string have 6 chars,
result -
010203010203
040506040506
070809070809
I attempted solving this on paper, and arrived at a similar solution to that of #mayamar's:
public String sqConcat(String string1, String string2)
{
String[] rows1 = string1.split("\n");
String[] rows2 = string2.split("\n");
return new String(rows1[0] + rows2[0] + "\n"
+ rows1[1] + rows2[1] + "\n"
+ rows1[2] + rows2[2] + "\n");
}
Thanks for the help, everyone.
I have two arraylists
ArrayList A ArrayList B
London 001
Berlin 001
Frankfurt 450
Rome 001
Geneva 230
Lille 620
What, I am trying to print out is the following:
If, the code in the arraylist are not equal then add separate XML tags to it. if they are equal then club them in a single tag.
E.g
<001> London Berlin </001> <450> Frankfurt </450> <001> Rome </001> <230> Geneva </230> <620> Lille </620>
Below is the logic which I am using
List<String> newList = new ArrayList<String>();
for(int i= 0; i< ListA.size(); i++){
if(i >=1){
String temp = ListB.get(i-1);
if(temp.contentEquals(ListB.get(i)))
{
newList.add(ListA.get(i));
}
else{
newList.add("<"+ ListB.get(i) +"> " + ListA.get(i) + " </"+ ListB.get(i) +">" );
}
}
else{
/*if i=0*/
newList.add("<"+ ListB.get(i) +"> " + ListA.get(i) + " </"+ ListB.get(i) +">" );
}
}
StringJoiner outputText = new StringJoiner(" ");
for(int i=0; i< newList.size();i++){
outputText.add(newList.get(i));
}
System.out.println(outputText.toString());
}
I understand there is a problem with the logic. Just got lost in loops.
your logic was wrong, try this one:
for (int i = 0; i < ListA.size(); i++) {
if (i == 0) {
newList.add("<" + ListB.get(i) + "> " + ListA.get(i) + " ");
}
if (i >= 1) {
String temp = ListB.get(i - 1);
if (temp.equals(ListB.get(i))) {
newList.add(ListA.get(i));
} else {
newList.add("</" + ListB.get(i - 1) + ">" + " <" + ListB.get(i) + "> " + ListA.get(i) + " ");
}
}
if (i == ListA.size() - 1) {
newList.add("</" + ListB.get(i) + ">");
}
}
by using this logic you will have exactly the desired output
see below:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class MultipleLists {
public static void main(String[] args) {
// London 001
// Berlin 001
// Frankfurt 450
// Rome 001
// Geneva 230
// Lille 620
List<String> cities = Arrays.asList("London", "Berlin", "Frankfurt", "Rome", "Geneva", "Lille");
List<String> codes = Arrays.asList("001", "001", "450", "001", "230", "620");
List<CityCode> cityCodes = new ArrayList<>();
for (int i = 0; i < cities.size(); i++) {
cityCodes.add(new CityCode(cities.get(i), codes.get(i)));
}
StringBuffer stringBuffer = new StringBuffer();
Collections.sort(codes);
Set<String> codesSet = new HashSet<>(codes);
for (String code : codesSet) {
stringBuffer.append("<" + code + ">");
for (CityCode cityCode : cityCodes) {
if (cityCode.getCode().compareTo(code) == 0) {
stringBuffer.append(cityCode.getName());
stringBuffer.append(" ");
}
}
stringBuffer.append("</" + code + ">");
}
System.out.println(stringBuffer); // <001>London Berlin Rome </001><620>Lille </620><230>Geneva </230><450>Frankfurt </450>
}
}
class CityCode {
private String name;
private String code;
public CityCode(String name, String code) {
this.name = name;
this.code = code;
}
public String getName() {
return name;
}
public String getCode() {
return code;
}
}
You need to make a minor change and that is to add the closing tags differently. Other code remains the same.
List<String> newList = new ArrayList<String>();
for(int i= 0; i< ListA.size(); i++){
if(i >=1){
String temp = ListB.get(i-1);
if(temp.contentEquals(ListB.get(i)))
{
newList.add(ListA.get(i));
}else{
newList.add(" </"+ ListB.get(i-1) +">" )
newList.add("<"+ ListB.get(i) +"> " + ListA.get(i) );
}
}else{
/*if i=0*/
newList.add("<"+ ListB.get(i) +"> " + ListA.get(i) + );
}
if(i==ListA.size()-1){
newList.add(" </"+ ListB.get(i-1) +">"
}
}
StringJoiner outputText = new StringJoiner(" ");
for(int i=0; i< newList.size();i++){
outputText.add(newList.get(i));
}
System.out.println(outputText.toString());
}
Hope it helps.
Something like this?
public static void main(String[] args) {
List<String> cities = Arrays.asList("London", "Berlin", "Frankfurt", "Rome", "Geneva", "Lille");
List<String> codes = Arrays.asList("001", "001", "450", "001", "230", "620");
Map<String, List<String>> result = new HashMap<>();
for (int i = 0; i < cities.size(); i++) {
String city = cities.get(i);
String code = codes.get(i);
if (result.containsKey(code)) {
List<String> list = result.get(code);
list.add(city);
} else {
ArrayList<String> mappedCities = new ArrayList<>();
mappedCities.add(city);
result.put(code, mappedCities);
}
}
String fullXml = result.entrySet().stream().parallel().map(entry -> {
String tag = entry.getKey();
List<String> vals = entry.getValue();
String citiesSeparated = vals.stream().collect(Collectors.joining(" "));
return xmlStart(tag) + citiesSeparated + xmlEnd(tag);
}).collect(Collectors.joining(" "));
System.out.println(fullXml);
}
private static String xmlEnd(String s) {
return "<" + s + "/>";
}
private static String xmlStart(String s) {
return "<" + s + ">";
}
First of all: having two disconnected Lists is not a good idea (very bad idea).
You highly depend on position of code and city in them. Maybe you can reconsider to use a Map instead? It will be much easier.
Second: it seems like you missed one requirement which is in your code.
"Join cities in one tag if code is equal to previous city code"
is it true or not? Why "Rome" with code 001 is in separate tag from "London Berlin"?
Third: Of course Jose's answer is correct OO answer which personally I prefer.
Forth: BTW if "Rome" must be in the same tag as "London Berlin" you can simply use a Map like:
Map<String,String> codeCityMap = new TreeMap<String,String>();
for (int i=0;i <arrayListA.size();i++)
{
String cities = codeCityMap.get(arrayListB.get(i));
cities = null == cities?arrayListA.get(i):cities + " " + arrayListA.get(i);
codeCityMap.put(arrayListB.get(i), cities);
}
List<String> newList = new ArrayList<String>();
for (String code: codeCityMap.keySet())
{
newList.add("<" + code + ">" + codeCityMap.get(code) + "</" + code + ">");
}
If "Rome" must not be you can use same technique, but introduce a little additional code to check also equality to to the previous citiy code in the line cities = null == cities?arrayListA.get(i):cities + " " + arrayListA.get(i);
if you need to main order or sort result use LinkedMap, TreeMap or do it on your own.
I am trying to reverse a String word by word using recursion. (Ex: "Hello my friend" is reversed to "friend my Hello") This is the code I have attempted to write for this method. I have tried multiple similar variations but the output is only ever the first or last word of the String. I believe the part that is "broken" is the first if statement, but I am not quite sure.
public static String reverse (String words) {
Scanner sc = new Scanner(words);
String backwards = "";
if (sc.hasNext()) {
String currentWord = sc.next();
reverse(sc.nextLine());
backwards = backwards + " " + currentWord;
} //end if
else {
backwards = words;
} //end else
return backwards;
}
I am aware that a few similar questions exist, but their answers have not seemed to help me understand my mistake(s).
Thanks!
Instead of using a Scanner, you can make use of an overload of String.split to split words around the first space:
public static String reverse(String words) {
String[] wordArr = words.split(" ", 2); // split into a maximum of 2 Strings
if (wordArr.length > 1) { // If there is more than 1 word
// return the first word (wordArr[0]),
// behind the reverse of the rest of the String (wordArr[1])
return reverse(wordArr[1]) + " " + wordArr[0];
}
return wordArr[0]; // else, just return the one word
}
You shouldn't call nextLine() because your input is all on one line. Your logic is much clearer if you begin by creating a simple helper method, it should take an array of words and a position; from there you can recursively build your desired output with something like
private static String reverse(String[] words, int p) {
if (p + 1 < words.length) {
return reverse(words, p + 1) + " " + words[p];
} else if (p < words.length) {
return words[p];
}
return "";
}
Then your public method is easy to implement, just split the original input on white space and call reverse starting at 0 (remembering to return the result). Like,
public static String reverse(String words) {
return reverse(words.split("\\s+"), 0);
}
And then, I tested it like
public static void main(String[] args) {
System.out.println(reverse("Hello my friend"));
}
Which outputs (as requested)
friend my Hello
Alternatively, you could make that helper take your Scanner instead like
private static String reverse(Scanner sc) {
if (sc.hasNext()) {
String currentWord = sc.next();
if (sc.hasNext()) {
return reverse(sc) + " " + currentWord;
}
return currentWord;
}
return "";
}
And then your public method is
public static String reverse(String words) {
return reverse(new Scanner(words));
}
public static String reverseSentence(String sentence) {
StringBuilder sb = new StringBuilder();
int firstSpace = sentence.indexOf(' ');
if (firstSpace == -1) {
return sb.append(sentence.strip()).append(" ").toString();
}
String secondPart = sentence.substring(firstSpace + 1);
String firstPart = sentence.substring(0, firstSpace);//similar to merger sort
return sb.append(reverseSentence(secondPart)).append(reverseSentence(firstPart)).toString();
}
You throw away the recursion results:
reverse(sc.nextLine());
backwards = backwards + " " + currentWord;
Instead, use this:
backwards = reverse(sc.nextLine());
backwards = backwards + " " + currentWord;
Better yet:
backwards = reverse(sc.nextLine()) + " " + currentWord;
As stated in the comments, you could use a StringBuilder instead of Scanner class.
This example sends the same words, splits them by spaces each time you enter the method and you send the index of the word to be added in the next iteration.
For example:
public class RecursiveReverse {
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) {
String stringToReverse = "Hello my friend!";
System.out.println(reverse(stringToReverse, stringToReverse.split(" ").length - 1));
}
public static String reverse(String words, int i) {
if (i >= 0) { //If the index of the words is greater or equals the first word
sb.append(words.split(" ")[i]); //We split it and append it to our StringBuilder
sb.append(" "); //We append a space
reverse(words, --i); //We do this again
}
return sb.toString(); //When the above condition doesn't match we return the StringBuilder object as a String (which contains the words reversed)
}
}
Which produces this output:
friend! my Hello
A better method would be passing a String array as parameter so you split only once (when sending the words as an array to the method) the String.
public class RecursiveReverse {
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) {
String stringToReverse = "Hello my friend!";
String words[] = stringToReverse.split(" ");
System.out.println(reverse(words, words.length - 1));
}
public static String reverse(String words[], int i) {
if (i >= 0) {
sb.append(words[i]);
sb.append(" ");
reverse(words, --i);
}
return sb.toString();
}
}
Do you must use recursion? You can do that without it.
public static String reverse(String words) {
String[] list = words.split(" ");
Collections.reverse(list);
String reversed = String.join(" ", list);
return reversed;
}
You must keep hold of the extracted words between calls in an accumulator. Here is an example.
public static String reverse(String words, String acc){
Scanner sc = new Scanner(words);
if(!sc.hasNext()){
return acc;
}
return reverse(sc.nextLine(), acc) + " " + sc.next();
}
You would call it like this.
reverse("Hello my friend", "");
It's not the most efficient implementation in the world, but yeah... It must work!
If you want a more efficient one, use a StringBuilder as the accumulator.
Basically the program is pretty simple:
it takes a list of names and makes each player verse every player but only once..
So ceri would play 5 games in a row but what I want to happen is it to be random..
public class hatpicking {
public static void main(String[] args) {
String[] Names = { "Ceri", "Matthew", "Harry", "Lewis", "Kwok", "James"};
List<String> Matches = new ArrayList<String>();
for(int i = 0; i < Names.length; i++){
for(int j = i + 1; j <Names.length; j++){
if(Names[i].equals(Names[j])){
continue;
}else{
Matches.add(Names[i] + " v" Names[j]);
System.out.println(Names[i] + " v " + Names[j]);
}
}
}
}
}
I'm sure there is an easier way to randomise stuff but i'm only getting back into Programming so I need the work where ever I can...
Pretty much I want to assign:
(Names[i] + " v " Names[j]);
to the ArrayList - Matches but obviously
Matches.add(Names[i] + " v" Names[j]);
does not work, any hints?
Matches.add(Names[i] + " v" Names[j]);
should be
Matches.add(Names[i] + " v" + Names[j]);
Eran's answer is correct and will fix your bug. However, on a side note, a word about Java naming conventions. In Java, class names should always start with a capital letter, so class hatpicking should be class Hatpicking. In addition, variable names should start with a lowercase letter, so Names and Matchesshould be names and matches.
My guess is you just want to randomize the matches. So just use the existing code you have and just shuffle the output.
For for best shuffling results use see Shuffling section in this link. http://bost.ocks.org/mike/algorithms/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class RandomMatch {
public void matchGenerator() {
List<String> availablePlayers = Arrays.asList("Ceri", "Matthew", "Harry", "Lewis", "Kwok", "James");
List<String> matches = new ArrayList<String>();
int MAX_PLAYERS = availablePlayers.size();
for(int i=0; i<MAX_PLAYERS; i++) {
String homePlayer = availablePlayers.get(i);
for(int j=i+1; j<MAX_PLAYERS; j++) {
String awayPlayer = availablePlayers.get(j);
if(!homePlayer.equals(awayPlayer)) {
String match = homePlayer + " vs. " + awayPlayer;
matches.add(match);
}
}
}
System.out.println("Match List\n");
for(String match : matches)
System.out.println(match);
shuffle(matches);
System.out.println("Shuffled Match List\n");
for(String match : matches)
System.out.println(match);
}
public void shuffle(List<String> matches) {
long seed = System.currentTimeMillis();
Collections.shuffle(matches, new Random(seed));
seed = System.currentTimeMillis();
Collections.shuffle(matches, new Random(seed));
}
public static void main(String[] args) {
RandomMatch randomMatch = new RandomMatch();
randomMatch.matchGenerator();
}
}
Without for () loops such as
for(int j =0; j < array.length; j++)
{
}
I want to be able to check if a string contains any of the strings in an array globally. So for() loops don't work.
I have tried
int arraylength;
while(arraylength < array.length()){
arraylength++; }
if(string.contains(array[arraylength]) {}
but this returns an error.
edit:
To clear it up:
I want to do something like
if (string.contains(**code that checks all strings in an array**)
So I can check if string contains any of the strings in an array. As I have mentioned, for loops DO NOT work because I want to be able to execute the line of code above ANYWHERE in the class.
You can do it like this:
String veryHugeString = ...;
String[] words = new String[] { ... };
boolean foundAtLeastOne = false;
for (String word : words) {
if (veryHugeString.indexOf(word) > 0) {
foundAtLeastOne = true;
System.out.println("Word: " + word + " is found");
break;
}
}
System.out.println("Found at least one : " + foundAtLeastOne);
Try use lambdaj (download here,website) and hamcrest (download here,website), this libraries are very powerfull for managing collections, the following code is very simple and works perfectly:
import static ch.lambdaj.Lambda.having;
import static ch.lambdaj.Lambda.on;
import static ch.lambdaj.Lambda.select;
import static org.hamcrest.Matchers.containsString;
import java.util.Arrays;
import java.util.List;
public class Test2 {
public static void main(String[] args) {
List<String> list = Arrays.asList("A","BB","DCA","D","x");
String strTofind = "C";
System.out.println("List: " + list.toString());
boolean match = select(list, having(on(String.class), containsString(strTofind))).size()>0;
System.out.println("The string " + strTofind + (!match?" not":"") + " exists");
strTofind = "X";
match = select(list, having(on(String.class), containsString(strTofind))).size()>0;
System.out.println("The string " + strTofind + (!match?" not":"") + " exists");
}
}
This shows:
List: [A, BB, DCA, D, x]
The string C exists
The string X not exists
Basically, in one line you can search the string is in any strinf of the array:
boolean match = select(list, having(on(String.class), containsString(strTofind))).size()>0;
With this libraries you can solve your problem in one line. You must add to your project: hamcrest-all-1.3.jar and lambdaj-2.4.jar Hope this will be useful.
Note: in my example i use a List then if you want use an array: Arrays.asList(array) (array is string[])
For loop:
for (String search : array) {
if (message.contains(search)) {
return true;
}
}
return false;
Lambdas:
return Arrays.stream(array).anyMatch(message::contains);
Give this a try
String longString = "This is a string.";
String[] stringArray = new String[]{"apple", "ball", "This", "cat"};
int index = 0;
while(index <stringArray.length){
if(longString.contains(stringArray[index])){
System.out.println("found: "+stringArray[index]);
}
index++;
}